diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index d768a0ce6ea8..42bf5d2f6f46 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -6154,11 +6154,11 @@ fingerprint = "B573 5118 0375 A872 FBBF 7770 B629 036B E399 EEE9"; }]; }; - mausch = { - email = "mauricioscheffer@gmail.com"; - github = "mausch"; - githubId = 95194; - name = "Mauricio Scheffer"; + masipcat = { + email = "jordi@masip.cat"; + github = "masipcat"; + githubId = 775189; + name = "Jordi Masip"; }; matejc = { email = "cotman.matej@gmail.com"; @@ -6214,6 +6214,12 @@ githubId = 136037; name = "Matthew Maurer"; }; + mausch = { + email = "mauricioscheffer@gmail.com"; + github = "mausch"; + githubId = 95194; + name = "Mauricio Scheffer"; + }; maxdamantus = { email = "maxdamantus@gmail.com"; github = "Maxdamantus"; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index dd6fa483281a..3a8289923201 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -130,6 +130,7 @@ ./programs/droidcam.nix ./programs/environment.nix ./programs/evince.nix + ./programs/feedbackd.nix ./programs/file-roller.nix ./programs/firejail.nix ./programs/fish.nix @@ -163,6 +164,7 @@ ./programs/partition-manager.nix ./programs/plotinus.nix ./programs/proxychains.nix + ./programs/phosh.nix ./programs/qt5ct.nix ./programs/screen.nix ./programs/sedutil.nix diff --git a/nixos/modules/programs/feedbackd.nix b/nixos/modules/programs/feedbackd.nix new file mode 100644 index 000000000000..bb14489a6f4d --- /dev/null +++ b/nixos/modules/programs/feedbackd.nix @@ -0,0 +1,32 @@ +{ pkgs, lib, config, ... }: + +with lib; + +let + cfg = config.programs.feedbackd; +in { + options = { + programs.feedbackd = { + enable = mkEnableOption '' + Whether to enable the feedbackd D-BUS service and udev rules. + + Your user needs to be in the `feedbackd` group to trigger effects. + ''; + package = mkOption { + description = '' + Which feedbackd package to use. + ''; + type = types.package; + default = pkgs.feedbackd; + }; + }; + }; + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + services.dbus.packages = [ cfg.package ]; + services.udev.packages = [ cfg.package ]; + + users.groups.feedbackd = {}; + }; +} diff --git a/nixos/modules/programs/phosh.nix b/nixos/modules/programs/phosh.nix new file mode 100644 index 000000000000..f6faf7990dd1 --- /dev/null +++ b/nixos/modules/programs/phosh.nix @@ -0,0 +1,167 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.phosh; + + # Based on https://source.puri.sm/Librem5/librem5-base/-/blob/4596c1056dd75ac7f043aede07887990fd46f572/default/sm.puri.OSK0.desktop + oskItem = pkgs.makeDesktopItem { + name = "sm.puri.OSK0"; + type = "Application"; + desktopName = "On-screen keyboard"; + exec = "${pkgs.squeekboard}/bin/squeekboard"; + categories = "GNOME;Core;"; + extraEntries = '' + OnlyShowIn=GNOME; + NoDisplay=true + X-GNOME-Autostart-Phase=Panel + X-GNOME-Provides=inputmethod + X-GNOME-Autostart-Notify=true + X-GNOME-AutoRestart=true + ''; + }; + + phocConfigType = types.submodule { + options = { + xwayland = mkOption { + description = '' + Whether to enable XWayland support. + + To start XWayland immediately, use `immediate`. + ''; + type = types.enum [ "true" "false" "immediate" ]; + default = "false"; + }; + cursorTheme = mkOption { + description = '' + Cursor theme to use in Phosh. + ''; + type = types.str; + default = "default"; + }; + outputs = mkOption { + description = '' + Output configurations. + ''; + type = types.attrsOf phocOutputType; + default = { + DSI-1 = { + scale = 2; + }; + }; + }; + }; + }; + + phocOutputType = types.submodule { + options = { + modeline = mkOption { + description = '' + One or more modelines. + ''; + type = types.either types.str (types.listOf types.str); + default = []; + example = [ + "87.25 720 776 848 976 1440 1443 1453 1493 -hsync +vsync" + "65.13 768 816 896 1024 1024 1025 1028 1060 -HSync +VSync" + ]; + }; + mode = mkOption { + description = '' + Default video mode. + ''; + type = types.nullOr types.str; + default = null; + example = "768x1024"; + }; + scale = mkOption { + description = '' + Display scaling factor. + ''; + type = types.nullOr types.ints.unsigned; + default = null; + example = 2; + }; + rotate = mkOption { + description = '' + Screen transformation. + ''; + type = types.enum [ + "90" "180" "270" "flipped" "flipped-90" "flipped-180" "flipped-270" null + ]; + default = null; + }; + }; + }; + + optionalKV = k: v: if v == null then "" else "${k} = ${builtins.toString v}"; + + renderPhocOutput = name: output: let + modelines = if builtins.isList output.modeline + then output.modeline + else [ output.modeline ]; + renderModeline = l: "modeline = ${l}"; + in '' + [output:${name}] + ${concatStringsSep "\n" (map renderModeline modelines)} + ${optionalKV "mode" output.mode} + ${optionalKV "scale" output.scale} + ${optionalKV "rotate" output.rotate} + ''; + + renderPhocConfig = phoc: let + outputs = mapAttrsToList renderPhocOutput phoc.outputs; + in '' + [core] + xwayland = ${phoc.xwayland} + ${concatStringsSep "\n" outputs} + [cursor] + theme = ${phoc.cursorTheme} + ''; +in { + options = { + programs.phosh = { + enable = mkEnableOption '' + Whether to enable, Phosh, related packages and default configurations. + ''; + phocConfig = mkOption { + description = '' + Configurations for the Phoc compositor. + ''; + type = types.oneOf [ types.lines types.path phocConfigType ]; + default = {}; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + pkgs.phoc + pkgs.phosh + pkgs.squeekboard + oskItem + ]; + + programs.feedbackd.enable = true; + + # https://source.puri.sm/Librem5/phosh/-/issues/303 + security.pam.services.phosh = { + text = '' + auth requisite pam_nologin.so + auth required pam_succeed_if.so user != root quiet_success + auth required pam_securetty.so + auth requisite pam_nologin.so + ''; + }; + + services.gnome3.core-shell.enable = true; + services.gnome3.core-os-services.enable = true; + services.xserver.displayManager.sessionPackages = [ pkgs.phosh ]; + + environment.etc."phosh/phoc.ini".source = + if builtins.isPath cfg.phocConfig then cfg.phocConfig + else if builtins.isString cfg.phocConfig then pkgs.writeText "phoc.ini" cfg.phocConfig + else pkgs.writeText "phoc.ini" (renderPhocConfig cfg.phocConfig); + }; +} diff --git a/pkgs/applications/misc/feedbackd/default.nix b/pkgs/applications/misc/feedbackd/default.nix index 34119c2006d4..1cf2fee37104 100644 --- a/pkgs/applications/misc/feedbackd/default.nix +++ b/pkgs/applications/misc/feedbackd/default.nix @@ -41,6 +41,11 @@ stdenv.mkDerivation rec { json-glib ]; + postInstall = '' + mkdir -p $out/lib/udev/rules.d + sed "s|/usr/libexec/|$out/libexec/|" < $src/debian/feedbackd.udev > $out/lib/udev/rules.d/90-feedbackd.rules + ''; + meta = with lib; { description = "A daemon to provide haptic (and later more) feedback on events"; homepage = "https://source.puri.sm/Librem5/feedbackd"; diff --git a/pkgs/applications/misc/phoc/default.nix b/pkgs/applications/misc/phoc/default.nix new file mode 100644 index 000000000000..6ef88fb07c65 --- /dev/null +++ b/pkgs/applications/misc/phoc/default.nix @@ -0,0 +1,84 @@ +{ lib +, stdenv +, fetchFromGitLab +, fetchpatch +, meson +, ninja +, pkg-config +, python3 +, wrapGAppsHook +, libinput +, gnome3 +, glib +, gtk3 +, wayland +, libdrm +, libxkbcommon +, wlroots +}: + +let + phocWlroots = wlroots.overrideAttrs (old: { + patches = (old.patches or []) ++ [ + # Temporary fix. Upstream report: https://source.puri.sm/Librem5/phosh/-/issues/422 + (fetchpatch { + name = "0001-Revert-layer-shell-error-on-0-dimension-without-anch.patch"; + url = "https://gitlab.alpinelinux.org/alpine/aports/-/raw/78fde4aaf1a74eb13a3f083cb6dfb29f578c3265/community/wlroots/0001-Revert-layer-shell-error-on-0-dimension-without-anch.patch"; + sha256 = "1zjn7mwdj21z0jsc2mz90cnrzk97yqkiq58qqgpjav4h4dgpfb38"; + }) + # To fix missing header `EGL/eglmesaext.h` dropped upstream + (fetchpatch { + name = "0002-stop-including-eglmesaext-h.patch"; + url = "https://github.com/swaywm/wlroots/commit/e18599b05e0f0cbeba11adbd489e801285470eab.patch"; + sha256 = "17ax4dyk0584yhs3lq8ija5bkainjf7psx9c9r50cr4jm9c0i37l"; + }) + ]; + }); +in stdenv.mkDerivation rec { + pname = "phoc"; + version = "0.7.0"; + + src = fetchFromGitLab { + domain = "source.puri.sm"; + owner = "Librem5"; + repo = pname; + rev = "v${version}"; + sha256 = "0afiyr2slg38ksrqn19zygsmjy9k5bpwv6n7zjas3s5djr6hch45"; + }; + + nativeBuildInputs = [ + meson + ninja + pkg-config + python3 + wrapGAppsHook + ]; + + buildInputs = [ + libdrm.dev + libxkbcommon + libinput + glib + gtk3 + gnome3.gnome-desktop + # For keybindings settings schemas + gnome3.mutter + wayland + phocWlroots + ]; + + mesonFlags = ["-Dembed-wlroots=disabled"]; + + postPatch = '' + chmod +x build-aux/post_install.py + patchShebangs build-aux/post_install.py + ''; + + meta = with lib; { + description = "Wayland compositor for mobile phones like the Librem 5"; + homepage = "https://source.puri.sm/Librem5/phoc"; + license = licenses.gpl3Plus; + maintainers = with maintainers; [ archseer masipcat zhaofengli ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/applications/window-managers/phosh/default.nix b/pkgs/applications/window-managers/phosh/default.nix new file mode 100644 index 000000000000..95faee74dbc7 --- /dev/null +++ b/pkgs/applications/window-managers/phosh/default.nix @@ -0,0 +1,158 @@ +{ lib +, stdenv +, fetchFromGitLab +, meson +, ninja +, pkg-config +, python3 +, wrapGAppsHook +, libhandy +, libxkbcommon +, pulseaudio +, glib +, gtk3 +, gnome3 +, gcr +, pam +, systemd +, upower +, wayland +, dbus +, xvfb_run +, phoc +, feedbackd +, networkmanager +, polkit +, libsecret +, writeText +}: + +let + gvc = fetchFromGitLab { + domain = "gitlab.gnome.org"; + owner = "GNOME"; + repo = "libgnome-volume-control"; + rev = "ae1a34aafce7026b8c0f65a43c9192d756fe1057"; + sha256 = "0a4qh5pgyjki904qf7qmvqz2ksxb0p8xhgl2aixfbhixn0pw6saw"; + }; + + executable = writeText "phosh" '' + PHOC_INI=@out@/share/phosh/phoc.ini + GNOME_SESSION_ARGS="--disable-acceleration-check --session=phosh --debug" + + if [ -f /etc/phosh/phoc.ini ]; then + PHOC_INI=/etc/phosh/phoc.ini + elif [ -f /etc/phosh/rootston.ini ]; then + # honor old configs + PHOC_INI=/etc/phosh/rootston.ini + fi + + # Run gnome-session through a login shell so it picks + # variables from /etc/profile.d (XDG_*) + [ -n "$WLR_BACKENDS" ] || WLR_BACKENDS=drm,libinput + export WLR_BACKENDS + exec "${phoc}/bin/phoc" -C "$PHOC_INI" \ + -E "bash -lc 'XDG_DATA_DIRS=$XDG_DATA_DIRS:\$XDG_DATA_DIRS ${gnome3.gnome-session}/bin/gnome-session $GNOME_SESSION_ARGS'" + ''; + +in stdenv.mkDerivation rec { + pname = "phosh"; + version = "0.10.2"; + + src = fetchFromGitLab { + domain = "source.puri.sm"; + owner = "Librem5"; + repo = pname; + rev = "v${version}"; + sha256 = "07i8wpzl7311dcf9s57s96qh1v672c75wv6cllrxx7fsmpf8fhx4"; + }; + + nativeBuildInputs = [ + meson + ninja + pkg-config + python3 + wrapGAppsHook + ]; + + buildInputs = [ + phoc + libhandy + libsecret + libxkbcommon + pulseaudio + glib + gcr + networkmanager + polkit + gnome3.gnome-control-center + gnome3.gnome-desktop + gnome3.gnome-session + gtk3 + pam + systemd + upower + wayland + feedbackd + ]; + + checkInputs = [ + dbus + xvfb_run + ]; + + # Temporarily disabled - Test is broken (SIGABRT) + doCheck = false; + + postUnpack = '' + rmdir $sourceRoot/subprojects/gvc + ln -s ${gvc} $sourceRoot/subprojects/gvc + ''; + + postPatch = '' + chmod +x build-aux/post_install.py + patchShebangs build-aux/post_install.py + ''; + + checkPhase = '' + runHook preCheck + export NO_AT_BRIDGE=1 + xvfb-run -s '-screen 0 800x600x24' dbus-run-session \ + --config-file=${dbus.daemon}/share/dbus-1/session.conf \ + meson test --print-errorlogs + runHook postCheck + ''; + + # Replace the launcher script with ours + postInstall = '' + substituteAll ${executable} $out/bin/phosh + ''; + + # Depends on GSettings schemas in gnome-shell + preFixup = '' + gappsWrapperArgs+=( + --prefix XDG_DATA_DIRS : "${gnome3.gnome-shell}/share/gsettings-schemas/${gnome3.gnome-shell.name}" + ) + ''; + + postFixup = '' + mkdir -p $out/share/wayland-sessions + ln -s $out/share/applications/sm.puri.Phosh.desktop $out/share/wayland-sessions/ + # The OSK0.desktop points to a dummy stub that's not needed + rm $out/share/applications/sm.puri.OSK0.desktop + ''; + + passthru = { + providedSessions = [ + "sm.puri.Phosh" + ]; + }; + + meta = with lib; { + description = "A pure Wayland shell prototype for GNOME on mobile devices"; + homepage = "https://source.puri.sm/Librem5/phosh"; + license = licenses.gpl3Plus; + maintainers = with maintainers; [ archseer jtojnar masipcat zhaofengli ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 17289ffaa5f6..c0a9de11c543 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7536,10 +7536,16 @@ in philter = callPackage ../tools/networking/philter { }; + phoc = callPackage ../applications/misc/phoc { + wlroots = wlroots_0_12; + }; + phodav = callPackage ../tools/networking/phodav { }; pim6sd = callPackage ../servers/pim6sd { }; + phosh = callPackage ../applications/window-managers/phosh { }; + pinentry = libsForQt5.callPackage ../tools/security/pinentry { libcap = if stdenv.isDarwin then null else libcap; };