diff --git a/docs/src/ref_impl/creating_appvm.md b/docs/src/ref_impl/creating_appvm.md index 9517408d2..565b1bc46 100644 --- a/docs/src/ref_impl/creating_appvm.md +++ b/docs/src/ref_impl/creating_appvm.md @@ -61,4 +61,4 @@ To create an App VM, do the following: * **name**: the name of the launcher; * **path**: path to the executable you want to run, like a graphical application; - * **icon**: path to an icon to show. If you have an icon package for your launcher, add it here as well: [packages/icon-pack/default.nix](https://github.com/tiiuae/ghaf/blob/main/packages/icon-pack/default.nix). \ No newline at end of file + * **icon**: an optional icon for the launcher. If not specified, the system will attempt to find an icon matching the `name`. You can set this to the name of an icon you expect to be available in the current icon theme (currently "Papirus," defined in `modules/desktop/graphics/labwc.nix`), or provide a full path to a specific icon file. \ No newline at end of file diff --git a/modules/common/services/desktop.nix b/modules/common/services/desktop.nix index 5230afcca..f3223588b 100644 --- a/modules/common/services/desktop.nix +++ b/modules/common/services/desktop.nix @@ -60,7 +60,7 @@ in # description = "Isolated General Browsing"; # vm = "Chromium"; # path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start chromium"; - # icon = "${pkgs.icon-pack}/chromium.svg"; + # icon = "chromium"; # } { @@ -68,7 +68,7 @@ in description = "Isolated Trusted Browsing"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm google-chrome"; - icon = "${pkgs.icon-pack}/thorium-browser.svg"; + icon = "thorium-browser"; } { # The SPKI fingerprint is calculated like this: @@ -78,7 +78,7 @@ in description = "Isolated General Browsing"; vm = "Chrome"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm chrome-vm google-chrome"; - icon = "${pkgs.icon-pack}/google-chrome.svg"; + icon = "google-chrome"; } { @@ -86,7 +86,7 @@ in description = "GlobalProtect VPN Client"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm gpclient"; - icon = "${pkgs.icon-pack}/yast-vpn.svg"; + icon = "yast-vpn"; } { @@ -94,35 +94,35 @@ in description = "Microsoft Email Client"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm outlook"; - icon = "${pkgs.icon-pack}/ms-outlook.svg"; + icon = "ms-outlook"; } { name = "Microsoft 365"; description = "Microsoft 365 Software Suite"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm office"; - icon = "${pkgs.icon-pack}/microsoft-365.svg"; + icon = "microsoft-365"; } { name = "Teams"; description = "Microsoft Teams Collaboration Application"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm teams"; - icon = "${pkgs.icon-pack}/teams-for-linux.svg"; + icon = "teams-for-linux"; } { name = "Text Editor"; description = "Simple Text Editor"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm gnome-text-editor"; - icon = "${pkgs.icon-pack}/org.gnome.TextEditor.svg"; + icon = "org.gnome.TextEditor"; } { name = "Xarchiver"; description = "File Compressor"; vm = "Business"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm business-vm xarchiver"; - icon = "${pkgs.icon-pack}/xarchiver.svg"; + icon = "xarchiver"; } { @@ -130,7 +130,7 @@ in description = "Secure Android-in-the-Cloud"; vm = "GALA"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start gala"; - icon = "${pkgs.icon-pack}/distributor-logo-android.svg"; + icon = "distributor-logo-android"; } { @@ -138,7 +138,7 @@ in description = "Isolated PDF Viewer"; vm = "Zathura"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm zathura-vm zathura"; - icon = "${pkgs.icon-pack}/document-viewer.svg"; + icon = "document-viewer"; } { @@ -146,7 +146,7 @@ in description = "General Messaging Application"; vm = "Comms"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm comms-vm element"; - icon = "${pkgs.icon-pack}/element-desktop.svg"; + icon = "element-desktop"; } { @@ -154,7 +154,7 @@ in description = "Teams Collaboration & Messaging Application"; vm = "Comms"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm comms-vm slack"; - icon = "${pkgs.icon-pack}/slack.svg"; + icon = "slack"; } { @@ -162,7 +162,6 @@ in description = "Zoom Videoconferencing Application"; vm = "Comms"; path = "${pkgs.givc-cli}/bin/givc-cli ${cliArgs} start --vm comms-vm zoom"; - icon = "${pkgs.icon-pack}/Zoom.svg"; } { @@ -183,21 +182,21 @@ in name = "File Manager"; description = "Organize & Manage Files"; path = "${pkgs.pcmanfm}/bin/pcmanfm"; - icon = "${pkgs.icon-pack}/system-file-manager.svg"; + icon = "system-file-manager"; } { name = "Bluetooth Settings"; description = "Manage Bluetooth Devices & Settings"; path = "${pkgs.bt-launcher}/bin/bt-launcher"; - icon = "${pkgs.icon-pack}/bluetooth-48.svg"; + icon = "bluetooth-48"; } { name = "Audio Control"; description = "System Audio Control"; path = "${pkgs.ghaf-audio-control}/bin/GhafAudioControlStandalone --pulseaudio_server=audio-vm:${toString pulseaudioTcpControlPort}"; - icon = "${pkgs.icon-pack}/preferences-sound.svg"; + icon = "preferences-sound"; } { @@ -218,7 +217,7 @@ in { name = "Control panel"; path = "${pkgs.ctrl-panel}/bin/ctrl-panel"; - icon = "${pkgs.icon-pack}/utilities-tweak-tool.svg"; + icon = "utilities-tweak-tool"; } ] ++ optionals config.ghaf.reference.programs.windows-launcher.enable [ @@ -226,7 +225,7 @@ in name = "Windows"; description = "Virtualized Windows System"; path = "${pkgs.virt-viewer}/bin/remote-viewer -f spice://${winConfig.spice-host}:${toString winConfig.spice-port}"; - icon = "${pkgs.icon-pack}/distributor-logo-windows.svg"; + icon = "distributor-logo-windows"; } ]; }; diff --git a/modules/desktop/graphics/demo-apps.nix b/modules/desktop/graphics/demo-apps.nix index 7763c3ed5..511910247 100644 --- a/modules/desktop/graphics/demo-apps.nix +++ b/modules/desktop/graphics/demo-apps.nix @@ -38,37 +38,37 @@ in name = "Google Chrome"; description = "Web Browser"; path = "${pkgs.google-chrome}/bin/google-chrome-stable --enable-features=UseOzonePlatform --ozone-platform=wayland"; - icon = "${pkgs.icon-pack}/google-chrome.svg"; + icon = "google-chrome"; } ++ lib.optional cfg.chromium { name = "Chromium"; description = "Web Browser"; path = "${pkgs.chromium}/bin/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; - icon = "${pkgs.icon-pack}/chromium.svg"; + icon = "chromium"; } ++ lib.optional cfg.firefox { name = "Firefox"; description = "Web Browser"; path = "${pkgs.firefox}/bin/firefox"; - icon = "${pkgs.icon-pack}/firefox.svg"; + icon = "firefox"; } ++ lib.optional cfg.element-desktop { name = "Element"; - description = "General Messing Application"; + description = "General Messaging Application"; path = "${pkgs.element-desktop}/bin/element-desktop --enable-features=UseOzonePlatform --ozone-platform=wayland"; - icon = "${pkgs.icon-pack}/element-desktop.svg"; + icon = "element-desktop"; } ++ lib.optional cfg.gala-app { name = "GALA"; description = "Secure Android-in-the-Cloud"; path = "${pkgs.gala-app}/bin/gala --enable-features=UseOzonePlatform --ozone-platform=wayland"; - icon = "${pkgs.icon-pack}/distributor-logo-android.svg"; + icon = "distributor-logo-android"; } ++ lib.optional cfg.zathura { name = "PDF Viewer"; description = "PDF Viewer Application"; path = "${pkgs.zathura}/bin/zathura"; - icon = "${pkgs.icon-pack}/document-viewer.svg"; + icon = "document-viewer"; }; }; } diff --git a/modules/desktop/graphics/ewwbar.nix b/modules/desktop/graphics/ewwbar.nix index 4bef25e36..06d13833f 100644 --- a/modules/desktop/graphics/ewwbar.nix +++ b/modules/desktop/graphics/ewwbar.nix @@ -644,8 +644,7 @@ in :spacing 10 :orientation "v" (etc) - (sys_sliders) - (settings_buttons)))) + (sys_sliders)))) ;; Power Menu Widget ;; (defwidget power-menu-widget [] @@ -830,7 +829,7 @@ in :halign "end" :valign "center" :spacing 14 - (systray :prepend-new true :class "tray") + (systray :orientation "h" :spacing 14 :prepend-new true :class "tray") (divider) ${lib.optionalString useGivc "(control :screen screen) (divider)"} (datetime-locale :screen screen) @@ -948,7 +947,7 @@ in * { color: $text-base; - font-family: "Inter"; + font-family: "${cfg.gtk.fontName}"; font-size: 14px; :disabled { color: $text-disabled; @@ -1091,7 +1090,7 @@ in .header { font-size: 0.9em; font-weight: 500; - font-family: Inter; + font-family: ${cfg.gtk.fontName}; } .settings{ @@ -1149,7 +1148,7 @@ in .title { font-size: 0.9em; font-weight: 500; - font-family: Inter; + font-family: ${cfg.gtk.fontName}; } .subtitle { @@ -1281,7 +1280,7 @@ in } .tray menu { - font-family: Inter; + font-family: ${cfg.gtk.fontName}; font-size: 1.1em; background-color: $bg-primary; @@ -1362,7 +1361,7 @@ in description = "eww-restart"; serviceConfig = { Type = "oneshot"; - ExecStart = "systemctl --user reload ewwbar.service"; + ExecStart = "systemctl --user try-reload-or-restart ewwbar.service"; Restart = "on-failure"; RestartSec = "100ms"; }; diff --git a/modules/desktop/graphics/ghaf-launcher.nix b/modules/desktop/graphics/ghaf-launcher.nix deleted file mode 100644 index 5dabb1c40..000000000 --- a/modules/desktop/graphics/ghaf-launcher.nix +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2024 TII (SSRC) and the Ghaf contributors -# SPDX-License-Identifier: Apache-2.0 -{ pkgs, ... }: -let - drawerCSS = pkgs.callPackage ./styles/launcher-style.nix { }; -in -pkgs.writeShellApplication { - name = "ghaf-launcher"; - runtimeInputs = [ - pkgs.coreutils - pkgs.nwg-drawer - pkgs.util-linux - ]; - bashOptions = [ ]; - text = '' - export XDG_CONFIG_HOME="$HOME/.config" - export XDG_CACHE_HOME="$HOME/.cache" - - # Temporary workaround - mkdir -p "$XDG_CACHE_HOME" "$XDG_CONFIG_HOME" - rm -rf "$HOME/.config/nwg-drawer" - #ln -s "${drawerCSS}/nwg-drawer" "$HOME/.config/" - - nwg-drawer -r -nofs -nocats -s ${drawerCSS} - ''; -} diff --git a/modules/desktop/graphics/labwc.config.nix b/modules/desktop/graphics/labwc.config.nix index 3cd0d067d..d941f05d0 100644 --- a/modules/desktop/graphics/labwc.config.nix +++ b/modules/desktop/graphics/labwc.config.nix @@ -11,16 +11,17 @@ let ghaf-screenshot = pkgs.callPackage ../../../packages/ghaf-screenshot { }; ghaf-workspace = pkgs.callPackage ../../../packages/ghaf-workspace { }; + drawerStyle = pkgs.callPackage ./styles/launcher-style.nix { }; inherit (config.ghaf.services.audio) pulseaudioTcpControlPort; gtklockStyle = pkgs.callPackage ./styles/lock-style.nix { }; lockCmd = "${pkgs.gtklock}/bin/gtklock -s ${gtklockStyle}"; - ghaf-launcher = pkgs.callPackage ./ghaf-launcher.nix { inherit config pkgs; }; autostart = pkgs.writeShellApplication { name = "labwc-autostart"; runtimeInputs = [ pkgs.systemd pkgs.dbus + pkgs.glib ]; text = @@ -45,6 +46,20 @@ let ${ghaf-workspace}/bin/ghaf-workspace switch "$current_workspace" fi ${ghaf-workspace}/bin/ghaf-workspace max 2 + + # Write the GTK settings to the settings.ini file in the GTK config directory + # Note: + # - On Wayland, GTK+ is known for not picking themes from settings.ini. + # - We define GTK+ theme on Wayland using gsettings (e.g., `gsettings set org.gnome.desktop.interface ...`). + mkdir -p "$XDG_CONFIG_HOME/gtk-3.0" + echo -e "${gtk_settings}" > "$XDG_CONFIG_HOME/gtk-3.0/settings.ini" + + gnome_schema="org.gnome.desktop.interface" + + gsettings set "$gnome_schema" gtk-theme "${cfg.gtk.theme}" + gsettings set "$gnome_schema" icon-theme "${cfg.gtk.iconTheme}" + gsettings set "$gnome_schema" font-name "${cfg.gtk.fontName} ${cfg.gtk.fontSize}" + gsettings set "$gnome_schema" color-scheme "${cfg.gtk.colorScheme}" '' + cfg.extraAutostart; }; @@ -56,13 +71,13 @@ let Ghaf yes - Inter + ${cfg.gtk.fontName} 12 normal bold - Inter + ${cfg.gtk.fontName} 12 normal bold @@ -202,13 +217,20 @@ let ''; makoConfig = '' - font=Inter 12 + font=${cfg.gtk.fontName} ${cfg.gtk.fontSize} background-color=#121212 progress-color=source #3D8252e6 border-radius=5 border-size=0 padding=10 - default-timeout=10000 + icons=1 + icon-path=/run/current-system/sw/share/icons/${cfg.gtk.iconTheme} + max-icon-size=32 + default-timeout=5000 + ignore-timeout=1 + + [app-name=blueman body~="(.*Authorization request.*)"] + invisible=1 ''; environment = '' @@ -220,6 +242,16 @@ let MOZ_ENABLE_WAYLAND=1 ''; + gtk_settings = '' + [Settings] + ${ + if cfg.gtk.colorScheme == "prefer-dark" then + "gtk-application-prefer-dark-theme = true" + else + "gtk-application-prefer-dark-theme = false" + } + ''; + labwc-session = pkgs.writeShellApplication { name = "labwc-session"; @@ -256,7 +288,7 @@ in description = "Ghaf launcher daemon"; serviceConfig = { Type = "simple"; - ExecStart = "${ghaf-launcher}/bin/ghaf-launcher"; + ExecStart = "${pkgs.nwg-drawer}/bin/nwg-drawer -r -nofs -nocats -s ${drawerStyle}"; Restart = "always"; RestartSec = "1"; }; @@ -298,6 +330,44 @@ in wantedBy = [ "ghaf-session.target" ]; }; + nm-applet = { + enable = true; + description = "network manager graphical interface."; + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = "1"; + ExecStart = "${pkgs.nm-launcher}/bin/nm-launcher"; + }; + wantedBy = [ "ghaf-session.target" ]; + partOf = [ "ghaf-session.target" ]; + }; + + # We use existing blueman services and create overrides for both + blueman-applet = { + enable = true; + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = "1"; + Environment = "DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/bt_applet_ssh_system_dbus.sock"; + ExecStart = [ + "" + "${pkgs.bt-launcher}/bin/bt-launcher applet" + ]; + }; + wantedBy = [ "ghaf-session.target" ]; + partOf = [ "ghaf-session.target" ]; + after = [ "ewwbar.service" ]; + }; + + blueman-manager = { + serviceConfig.ExecStart = [ + "" + "${pkgs.bt-launcher}/bin/bt-launcher" + ]; + }; + autolock = lib.mkIf cfg.autolock.enable { enable = true; description = "System autolock"; @@ -317,6 +387,7 @@ in }; partOf = [ "ghaf-session.target" ]; wantedBy = [ "ghaf-session.target" ]; + after = [ "ewwbar.service" ]; }; }; }; diff --git a/modules/desktop/graphics/labwc.nix b/modules/desktop/graphics/labwc.nix index 7630c6e16..5e2dfd711 100644 --- a/modules/desktop/graphics/labwc.nix +++ b/modules/desktop/graphics/labwc.nix @@ -81,6 +81,49 @@ in default = [ ]; description = "Wayland security context settings"; }; + gtk = lib.mkOption { + type = lib.types.submodule { + options = { + theme = lib.mkOption { + type = lib.types.str; + example = "Adwaita"; + description = "Basename of the default theme used by gtk+."; + }; + iconTheme = lib.mkOption { + type = lib.types.str; + example = "Papirus"; + description = "Name of the default icon theme used by gtk+."; + }; + colorScheme = lib.mkOption { + type = lib.types.enum [ + "default" + "prefer-dark" + "prefer-light" + ]; + example = "prefer-dark"; + description = "The preferred color scheme for gtk+. Valid values are 'default', 'prefer-dark', 'prefer-light'."; + }; + fontName = lib.mkOption { + type = lib.types.str; + example = "Cantarell"; + description = "The preferred font family."; + }; + fontSize = lib.mkOption { + type = lib.types.nullOr lib.types.str; + example = "11"; + description = "The preferred default font size."; + }; + }; + }; + default = { + theme = "Adwaita"; + iconTheme = "Papirus"; + colorScheme = "prefer-dark"; + fontName = "Cantarell"; + fontSize = "11"; + }; + description = "Global gtk+ configuration"; + }; extraAutostart = lib.mkOption { type = lib.types.str; default = ""; @@ -91,22 +134,31 @@ in config = lib.mkIf cfg.enable { ghaf.graphics.login-manager.enable = true; - environment.systemPackages = - [ - pkgs.labwc - pkgs.ghaf-theme - pkgs.adwaita-icon-theme + environment = { + systemPackages = + [ + pkgs.labwc + pkgs.ghaf-theme + pkgs.papirus-icon-theme - (import ./launchers.nix { inherit pkgs config; }) - ] - # Grim screenshot tool is used for labwc debug-builds - # satty and slurp add some functionality to bring it - # a more modern selection tool - ++ lib.optionals config.ghaf.profiles.debug.enable [ - pkgs.grim - pkgs.satty - pkgs.slurp - ]; + (import ./launchers.nix { inherit pkgs config; }) + ] + # Grim screenshot tool is used for labwc debug-builds + # satty and slurp add some functionality to bring it + # a more modern selection tool + ++ lib.optionals config.ghaf.profiles.debug.enable [ + pkgs.grim + pkgs.satty + pkgs.slurp + ]; + sessionVariables = { + XDG_CONFIG_HOME = "$HOME/.config"; + XDG_DATA_HOME = "$HOME/.local/share"; + XDG_STATE_HOME = "$HOME/.local/state"; + XDG_CACHE_HOME = "$HOME/.cache"; + GSETTINGS_SCHEMA_DIR = "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}/glib-2.0/schemas"; + }; + }; # It will create a /etc/pam.d/ file for authentication security.pam.services.gtklock = { }; @@ -127,12 +179,14 @@ in services.upower.enable = true; fonts.fontconfig.defaultFonts.sansSerif = [ "Inter" ]; + # dconf is necessary for gsettings to work + programs.dconf.enable = true; + ghaf.graphics.launchers = lib.mkIf config.ghaf.profiles.debug.enable [ { name = "Terminal"; description = "System Terminal"; path = "${pkgs.foot}/bin/foot"; - icon = "${pkgs.icon-pack}/utilities-terminal.svg"; } ]; }; diff --git a/modules/desktop/graphics/launchers.nix b/modules/desktop/graphics/launchers.nix index 291e158f7..cf302cbd0 100644 --- a/modules/desktop/graphics/launchers.nix +++ b/modules/desktop/graphics/launchers.nix @@ -6,22 +6,27 @@ let elem: let prefix = if elem.vm != null then "[${elem.vm}] " else ""; + icon = if elem.icon != null then elem.icon else elem.name; + + extraCheckPhase = + if builtins.isPath icon then + '' + # Check that the icon's path exists + [[ -f "${icon}" ]] || (echo "The icon's path ${icon} doesn't exist" && exit 1) + '' + else + ""; in (pkgs.makeDesktopItem { - inherit (elem) name icon; + inherit (elem) name; genericName = elem.name; desktopName = elem.name; + inherit icon; comment = "${prefix}${elem.description}"; exec = elem.path; }).overrideAttrs (prevAttrs: { - checkPhase = - prevAttrs.checkPhase - + '' - - # Check that the icon's path exists - [[ -f "${elem.icon}" ]] || (echo "The icon's path ${elem.icon} doesn't exist" && exit 1) - ''; + checkPhase = prevAttrs.checkPhase + extraCheckPhase; }); in pkgs.symlinkJoin { diff --git a/modules/desktop/graphics/waybar.config.nix b/modules/desktop/graphics/waybar.config.nix index cd309e5ec..373cf4a52 100644 --- a/modules/desktop/graphics/waybar.config.nix +++ b/modules/desktop/graphics/waybar.config.nix @@ -27,7 +27,6 @@ in name = "Terminal"; description = "System Terminal"; path = "${pkgs.foot}/bin/foot"; - icon = "${pkgs.icon-pack}/utilities-terminal.svg"; } ]; environment.etc."waybar/config" = { diff --git a/modules/desktop/profiles/graphics.nix b/modules/desktop/profiles/graphics.nix index f4124f4b4..59e27c236 100644 --- a/modules/desktop/profiles/graphics.nix +++ b/modules/desktop/profiles/graphics.nix @@ -73,8 +73,13 @@ in type = types.path; }; icon = mkOption { - description = "Path of the icon"; - type = types.path; + description = '' + Optional icon for the launcher. If unspecified, active icon theme will + be searched to find an icon matching the launcher name. Can be set to an + icon name from the current theme (Papirus) or a full path to an icon file. + ''; + type = types.nullOr (types.path // types.str); + default = null; }; }; } diff --git a/modules/microvm/virtualization/microvm/guivm.nix b/modules/microvm/virtualization/microvm/guivm.nix index 88e6f27c7..4f1714442 100644 --- a/modules/microvm/virtualization/microvm/guivm.nix +++ b/modules/microvm/virtualization/microvm/guivm.nix @@ -141,6 +141,7 @@ let ++ lib.optionals config.ghaf.profiles.debug.enable [ pkgs.glxinfo pkgs.libva-utils + pkgs.glib ]; sessionVariables = { XDG_PICTURES_DIR = "$HOME/Pictures"; @@ -205,18 +206,9 @@ let ghaf.reference.services.ollama = true; - systemd.user.services.nm-applet = { - enable = true; - description = "network manager graphical interface."; - serviceConfig = { - Type = "simple"; - Restart = "always"; - RestartSec = "1"; - ExecStart = "${pkgs.nm-launcher}/bin/nm-launcher"; - }; - partOf = [ "ghaf-session.target" ]; - wantedBy = [ "ghaf-session.target" ]; - }; + # We dont enable services.blueman because it adds blueman desktop entry + services.dbus.packages = [ pkgs.blueman ]; + systemd.packages = [ pkgs.blueman ]; } ) ]; diff --git a/modules/reference/programs/windows-launcher.nix b/modules/reference/programs/windows-launcher.nix index 79a6affb1..1a63f9532 100644 --- a/modules/reference/programs/windows-launcher.nix +++ b/modules/reference/programs/windows-launcher.nix @@ -38,7 +38,7 @@ in name = "Windows"; description = "Virtualized Windows System"; path = "${windows-launcher}/bin/windows-launcher-ui"; - icon = "${pkgs.icon-pack}/distributor-logo-windows.svg"; + icon = "distributor-logo-windows"; } ]; diff --git a/overlays/custom-packages/default.nix b/overlays/custom-packages/default.nix index 395d9676c..8783b7ab8 100644 --- a/overlays/custom-packages/default.nix +++ b/overlays/custom-packages/default.nix @@ -13,7 +13,6 @@ qemu_kvm = import ./qemu { inherit final prev; }; nm-launcher = final.callPackage ../../packages/nm-launcher { }; bt-launcher = final.callPackage ../../packages/bt-launcher { }; - icon-pack = final.callPackage ../../packages/icon-pack { }; labwc = import ./labwc { inherit prev; }; tpm2-pkcs11 = import ./tpm2-pkcs11 { inherit prev; }; waybar = import ./waybar { inherit prev; }; diff --git a/packages/bt-launcher/default.nix b/packages/bt-launcher/default.nix index a63e207c0..8f079c765 100644 --- a/packages/bt-launcher/default.nix +++ b/packages/bt-launcher/default.nix @@ -11,52 +11,88 @@ }: writeShellApplication { name = "bt-launcher"; + runtimeInputs = [ + gawk + blueman + openssh + bluez + ]; text = '' + tunnel_name="/tmp/control_socket_bt" export PULSE_SERVER=audio-vm:4714 - export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/ssh_session_dbus.sock - export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/ssh_system_dbus.sock - ${openssh}/bin/ssh -M -S /tmp/control_socket_bt \ - -f -N -q ghaf@audio-vm \ - -i /run/waypipe-ssh/id_ed25519 \ - -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - -o StreamLocalBindUnlink=yes \ - -o ExitOnForwardFailure=yes \ - -L /tmp/ssh_session_dbus.sock:/run/user/1000/bus \ - -L /tmp/ssh_system_dbus.sock:/run/dbus/system_bus_socket - # Use the control socket to close the ssh tunnel. + + open-tunnel() { + local socket_path="$1" + local remote_user="ghaf" + local remote_host="audio-vm" + local local_bind="$2" + local remote_bind="$3" + + export DBUS_SYSTEM_BUS_ADDRESS=unix:path="$local_bind" + ssh -M -S "$socket_path" \ + -f -N -q $remote_user@$remote_host \ + -i /run/waypipe-ssh/id_ed25519 \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o StreamLocalBindUnlink=yes \ + -o ExitOnForwardFailure=yes \ + -L "$local_bind:$remote_bind" + } + close-tunnel() { - ${openssh}/bin/ssh -q -S /tmp/control_socket_bt -O exit ghaf@audio-vm + local socket_path="$1" + ssh -q -S "$socket_path" -O exit ghaf@audio-vm } launch-blueman() { - ${blueman}/bin/blueman-applet & - ${blueman}/bin/blueman-manager - close-tunnel + open-tunnel "$tunnel_name" "/tmp/bt_ssh_system_dbus.sock" "/run/dbus/system_bus_socket" + blueman-manager + close-tunnel "$tunnel_name" + } + + applet() { + local applet_socket="/tmp/control_socket_bt_applet" + open-tunnel "$applet_socket" "/tmp/bt_applet_ssh_system_dbus.sock" "/run/dbus/system_bus_socket" + blueman-applet + close-tunnel "$applet_socket" } status() { + open-tunnel "$tunnel_name" "/tmp/bt_ssh_system_dbus.sock" "/run/dbus/system_bus_socket" # Get Bluetooth adapter details using bluetoothctl - BT_INFO=$(${bluez}/bin/bluetoothctl show) + BT_INFO=$(bluetoothctl show) # Extract relevant fields - BT_POWERED=$(echo "$BT_INFO" | grep "Powered:" | ${gawk}/bin/awk '{print $2}') - BT_DISCOVERABLE=$(echo "$BT_INFO" | grep "Discoverable:" | ${gawk}/bin/awk '{print $2}') - BT_PAIRABLE=$(echo "$BT_INFO" | grep "Pairable:" | ${gawk}/bin/awk '{print $2}') - BT_DISCOVERING=$(echo "$BT_INFO" | grep "Discovering:" | ${gawk}/bin/awk '{print $2}') + BT_POWERED=$(echo "$BT_INFO" | grep "Powered:" | awk '{print $2}') + BT_DISCOVERABLE=$(echo "$BT_INFO" | grep "Discoverable:" | awk '{print $2}') + BT_PAIRABLE=$(echo "$BT_INFO" | grep "Pairable:" | awk '{print $2}') + BT_DISCOVERING=$(echo "$BT_INFO" | grep "Discovering:" | awk '{print $2}') BT_ALIAS=$(echo "$BT_INFO" | grep "Alias:" | cut -d' ' -f2-) status="{\"powered\":\"$BT_POWERED\",\"discoverable\":\"$BT_DISCOVERABLE\",\"pairable\":\"$BT_PAIRABLE\",\"discovering\":\"$BT_DISCOVERING\",\"alias\":\"$BT_ALIAS\"}" echo "$status" - close-tunnel + close-tunnel "$tunnel_name" } if [ $# -eq 0 ]; then launch-blueman - elif [ "$1" = "status" ]; then - status fi + + case "$1" in + status) + status + ;; + applet) + applet + ;; + close) + applet + ;; + *) + echo "Unknown option" + ;; + esac ''; meta = { diff --git a/packages/icon-pack/default.nix b/packages/icon-pack/default.nix deleted file mode 100644 index 08a1afcce..000000000 --- a/packages/icon-pack/default.nix +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2024 TII (SSRC) and the Ghaf contributors -# SPDX-License-Identifier: Apache-2.0 -# -# This package contains only the assets that we need from papirus-icon-theme, -# so we don't include the entire theme in the distribution. -{ - lib, - runCommand, - papirus-icon-theme, -}: -let - icons = [ - "bluetooth-48.svg" - "preferences-sound.svg" - "chromium.svg" - "distributor-logo-android.svg" - "distributor-logo-windows.svg" - "document-viewer.svg" - "element-desktop.svg" - "firefox.svg" - "microsoft-365.svg" - "ms-outlook.svg" - "org.gnome.TextEditor.svg" - "preferences-system-network.svg" - "slack.svg" - "system-lock-screen.svg" - "system-log-out.svg" - "system-reboot.svg" - "system-shutdown.svg" - "system-suspend-hibernate.svg" - "system-suspend.svg" - "teams-for-linux.svg" - "thorium-browser.svg" - "utilities-terminal.svg" - "xarchiver.svg" - "yast-vpn.svg" - "system-file-manager.svg" - "utilities-tweak-tool.svg" - "Zoom.svg" - "google-chrome.svg" - ]; -in -runCommand "icon-pack" - { - # Preserve Papirus license - meta.license = papirus-icon-theme.meta.license; - } - '' - mkdir -p $out - # All SVGs are located inside 64x64, all other sizes are symlinks. - - ${lib.concatStringsSep "\n" ( - map (icon: '' - cp ${papirus-icon-theme}/share/icons/Papirus/64x64/apps/${icon} $out/ - '') icons - )} - '' diff --git a/packages/nm-launcher/default.nix b/packages/nm-launcher/default.nix index 5bdb38439..c85b3edb2 100644 --- a/packages/nm-launcher/default.nix +++ b/packages/nm-launcher/default.nix @@ -17,7 +17,7 @@ writeShellApplication { text = '' # Keep only system dbus so nm-applet can talk to network-manager deaemon on net-vm. # export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/ssh_session_dbus.sock - export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/ssh_system_dbus.sock + export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/nm_ssh_system_dbus.sock ${openssh}/bin/ssh -M -S /tmp/control_socket \ -f -N -q ghaf@net-vm \ -i /run/waypipe-ssh/id_ed25519 \ @@ -25,8 +25,7 @@ writeShellApplication { -o UserKnownHostsFile=/dev/null \ -o StreamLocalBindUnlink=yes \ -o ExitOnForwardFailure=yes \ - -L /tmp/ssh_session_dbus.sock:/run/user/1000/bus \ - -L /tmp/ssh_system_dbus.sock:/run/dbus/system_bus_socket + -L /tmp/nm_ssh_system_dbus.sock:/run/dbus/system_bus_socket ${networkmanagerapplet}/bin/nm-applet --indicator # Use the control socket to close the ssh tunnel. ${openssh}/bin/ssh -q -S /tmp/control_socket -O exit ghaf@net-vm