diff --git a/assets/icons/svg/admin-cog.svg b/assets/icons/svg/admin-cog.svg new file mode 100644 index 0000000000..5c1349bf1c --- /dev/null +++ b/assets/icons/svg/admin-cog.svg @@ -0,0 +1,47 @@ + + + + + + + diff --git a/assets/icons/svg/ghaf-white.svg b/assets/icons/svg/ghaf-white.svg new file mode 100644 index 0000000000..99582ab347 --- /dev/null +++ b/assets/icons/svg/ghaf-white.svg @@ -0,0 +1,43 @@ + + + + + + + diff --git a/assets/icons/svg/launchpad.svg b/assets/icons/svg/launchpad.svg new file mode 100644 index 0000000000..5970b468ef --- /dev/null +++ b/assets/icons/svg/launchpad.svg @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/assets/wallpaper-plain.png b/assets/wallpaper-plain.png new file mode 100644 index 0000000000..b9fe8d5216 Binary files /dev/null and b/assets/wallpaper-plain.png differ diff --git a/lib/icons.nix b/lib/icons.nix new file mode 100644 index 0000000000..3afe0e95da --- /dev/null +++ b/lib/icons.nix @@ -0,0 +1,94 @@ +# Copyright 2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{pkgs, ...}: rec { + /* + * + Resizes a PNG to fit the given size. + + # Inputs + + `name` + + : Name of the file, this will be included in the output filename. + + `path` + + : Path of the original PNG file to be resized. + + `size` + + : The new size for the image (x). + + # Type + + ``` + resizePNG :: [String] -> [String] -> [String] -> [String] + ``` + + # Example + :::{.example} + ## Simple example + + ```nix + resizePNG "my-icon" ./my-icon-hi-res.png "24x24"; + ``` + + ::: + + */ + resizePNG = name: path: size: let + out = pkgs.runCommand "${name}-${size}" {} '' + mkdir -p $out + ${pkgs.buildPackages.imagemagick}/bin/convert \ + ${path} \ + -resize ${size} \ + $out/${name}.png + ''; + in "${out}/${name}.png"; + + /* + * + Converts an SVG file to a PNG of a specific size. + + # Inputs + + `name` + + : Name of the file, this will be included in the output filename. + + `path` + + : Path of the original SVG file to be converted. + + `size` + + : The size of the PNG image to be rendered. + + # Type + + ``` + svgToPNG :: [String] -> [String] -> [String] -> [String] + ``` + + # Example + :::{.example} + ## Simple example + + ```nix + svgToPNG "my-icon" ./my-icon.svg "24x24"; + ``` + + ::: + + */ + svgToPNG = name: path: size: let + sizes = builtins.split "x" size; + width = builtins.head sizes; + height = builtins.elemAt sizes 2; + out = pkgs.runCommand "${name}-${size}" {} '' + mkdir -p $out + ${pkgs.librsvg}/bin/rsvg-convert ${path} -o $out/${name}.png \ + --width=${width} --height=${height} --keep-aspect-ratio + ''; + in "${out}/${name}.png"; +} diff --git a/modules/desktop/graphics/demo-apps.nix b/modules/desktop/graphics/demo-apps.nix index 5c10fc0720..ef5c48ff8e 100644 --- a/modules/desktop/graphics/demo-apps.nix +++ b/modules/desktop/graphics/demo-apps.nix @@ -7,17 +7,12 @@ ... }: let cfg = config.ghaf.graphics.demo-apps; + inherit (import ../../../lib/icons.nix {inherit pkgs lib;}) resizePNG; /* Scaled down firefox icon */ - firefox-icon = pkgs.runCommand "firefox-icon-24x24" {} '' - mkdir -p $out/share/icons/hicolor/24x24/apps - ${pkgs.buildPackages.imagemagick}/bin/convert \ - ${pkgs.firefox}/share/icons/hicolor/128x128/apps/firefox.png \ - -resize 24x24 \ - $out/share/icons/hicolor/24x24/apps/firefox.png - ''; + firefox-icon = resizePNG "firefox" "${pkgs.firefox}/share/icons/hicolor/128x128/apps/firefox.png" "24x24"; /* Generate launchers to be used in weston.ini diff --git a/modules/desktop/graphics/fonts.nix b/modules/desktop/graphics/fonts.nix index 8db6814d82..75258d7e59 100644 --- a/modules/desktop/graphics/fonts.nix +++ b/modules/desktop/graphics/fonts.nix @@ -10,6 +10,7 @@ in { config = lib.mkIf (weston.enable || labwc.enable) { fonts.packages = with pkgs; [ + inter fira-code-nerdfont hack-font ]; diff --git a/modules/desktop/graphics/ghaf-launcher.nix b/modules/desktop/graphics/ghaf-launcher.nix index c79b05b4c5..59122a355b 100644 --- a/modules/desktop/graphics/ghaf-launcher.nix +++ b/modules/desktop/graphics/ghaf-launcher.nix @@ -10,22 +10,31 @@ drawerCSS = writeTextDir "nwg-drawer/drawer.css" '' /* Example configuration from: https://github.com/nwg-piotr/nwg-drawer/blob/main/drawer.css */ window { - background-color: rgba (43, 48, 59, 0.95); - color: #eeeeee + background-color: rgba(32, 32, 32, 0.9); + color: #eeeeee; + border-radius: 7px; + border: 1px solid rgba(21, 36, 24, 0.3); + box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; } /* search entry */ entry { - background-color: rgba (0, 0, 0, 0.2) + background-color: rgba (43, 43, 43, 1); + border: 1px solid rgba(46, 46, 46, 1); + } + entry:focus { + box-shadow: none; + border: 1px solid rgba(223, 92, 55, 1); } button, image { background: none; - border: none + border: none; + box-shadow: none; } button:hover { - background-color: rgba (255, 255, 255, 0.1) + background-color: rgba (255, 255, 255, 0.06) } /* in case you wanted to give category buttons a different look */ @@ -51,5 +60,5 @@ in export XDG_CONFIG_HOME=${drawerCSS} export XDG_CACHE_HOME=$HOME/.cache ${coreutils}/bin/mkdir -p $XDG_CACHE_HOME - ${nwg-drawer}/bin/nwg-drawer + ${nwg-drawer}/bin/nwg-drawer -mb 20 -ml 440 -mr 440 -mt 420 -nofs -nocats '' diff --git a/modules/desktop/graphics/labwc.nix b/modules/desktop/graphics/labwc.nix index cd8d087d2e..79998945dc 100644 --- a/modules/desktop/graphics/labwc.nix +++ b/modules/desktop/graphics/labwc.nix @@ -7,6 +7,15 @@ ... }: let cfg = config.ghaf.graphics.labwc; + makoConfig = '' + font=Inter 12 + background-color=#202020e6 + progress-color=source #3D8252e6 + border-radius=5 + border-size=0 + padding=10 + default-timeout=10000 + ''; autostart = pkgs.writeScriptBin "labwc-autostart" '' # Import WAYLAND_DISPLAY variable to make it available to waypipe and other systemd services @@ -22,7 +31,7 @@ ${pkgs.waybar}/bin/waybar -s /etc/waybar/style.css -c /etc/waybar/config >/dev/null 2>&1 & # Enable notifications. - ${pkgs.mako}/bin/mako >/dev/null 2>&1 & + ${pkgs.mako}/bin/mako -c /etc/mako/config >/dev/null 2>&1 & ${lib.optionalString cfg.lock.enable '' # Lock screen after 5 minutes @@ -35,8 +44,27 @@ rcXml = '' - 10 + 5 + + + Inter + 10 + normal + normal + + + Inter + 12 + normal + bold + + + ${lib.optionalString config.ghaf.profiles.debug.enable '' + + + + ''} @@ -46,9 +74,78 @@ '') cfg.frameColouring)} + + yes + ''; + themeRc = '' + # general + border.width: 3 + padding.height: 6 + + # The following options has no default, but fallbacks back to + # font-height + 2x padding.height if not set. + # titlebar.height: + + # window border + window.active.border.color: #1d1d1d + window.inactive.border.color: #353535 + + # ToggleKeybinds status indicator + window.active.indicator.toggled-keybind.color: #f15025 + + # window titlebar background + window.active.title.bg.color: #1d1d1d + window.inactive.title.bg.color: #353535 + + # window titlebar text + window.active.label.text.color: #ffffff + window.inactive.label.text.color: #bbbbbb + window.label.text.justify: center + + # window buttons + window.active.button.unpressed.image.color: #ffffff + window.inactive.button.unpressed.image.color: #ffffff + + # Note that "menu", "iconify", "max", "close" buttons colors can be defined + # individually by inserting the type after the button node, for example: + # + # window.active.button.iconify.unpressed.image.color: #333333 + + # menu + menu.overlap.x: 0 + menu.overlap.y: 0 + menu.width.min: 20 + menu.width.max: 200 + menu.items.bg.color: #353535 + menu.items.text.color: #ffffff + menu.items.active.bg.color: #1d1d1d + menu.items.active.text.color: #ffffff + menu.items.padding.x: 7 + menu.items.padding.y: 4 + menu.separator.width: 1 + menu.separator.padding.width: 6 + menu.separator.padding.height: 3 + menu.separator.color: #2b2b2b + + # on screen display (window-cycle dialog) + osd.bg.color: #1d1d1d + osd.border.color: #ffffff + osd.border.width: 1 + osd.label.text.color: #ffffff + + osd.window-switcher.width: 600 + osd.window-switcher.padding: 4 + osd.window-switcher.item.padding.x: 10 + osd.window-switcher.item.padding.y: 1 + osd.window-switcher.item.active.border.width: 2 + + osd.workspace-switcher.boxes.width: 20 + osd.workspace-switcher.boxes.height: 20 + ''; + menuXml = '' @@ -62,13 +159,15 @@ - - - - + + + + + ''; launchers = pkgs.callPackage ./launchers.nix {inherit config;}; @@ -91,7 +190,7 @@ in { }; colour = lib.mkOption { type = lib.types.str; - example = "#00ffff"; + example = "#006305"; description = "Colour of the window frame"; }; }; @@ -99,7 +198,22 @@ in { default = [ { identifier = "foot"; - colour = "#00ffff"; + colour = "#006305"; + } + # TODO these should reference the VM and not the application that is + # relayed through waypipe. Ideally this would match using metadata + # through Wayland security context. + { + identifier = "dev.scpp.saca.gala"; + colour = "#027d7b"; + } + { + identifier = "chromium-browser"; + colour = "#630505"; + } + { + identifier = "org.pwmt.zathura"; + colour = "#122263"; } ]; description = "List of applications and their frame colours"; @@ -127,9 +241,13 @@ in { environment.etc = { "labwc/rc.xml".text = rcXml; "labwc/menu.xml".text = menuXml; - "labwc/themerc".source = "${pkgs.labwc}/share/doc/labwc/themerc"; + "labwc/themerc-override".text = themeRc; + + "mako/config".text = makoConfig; }; + fonts.fontconfig.defaultFonts.sansSerif = ["Inter"]; + # Next 2 services/targets are taken from official weston documentation # and adjusted for labwc # https://wayland.pages.freedesktop.org/weston/toc/running-weston.html diff --git a/modules/desktop/graphics/waybar.config.nix b/modules/desktop/graphics/waybar.config.nix index 16e7117c91..76386510d7 100644 --- a/modules/desktop/graphics/waybar.config.nix +++ b/modules/desktop/graphics/waybar.config.nix @@ -8,14 +8,11 @@ }: let cfg = config.ghaf.graphics.labwc; networkDevice = config.ghaf.hardware.definition.network.pciDevices; + inherit (import ../../../lib/icons.nix {inherit pkgs lib;}) svgToPNG; - ghaf-icon = pkgs.runCommand "ghaf-icon-24x24" {} '' - mkdir -p $out/share/icons/hicolor/24x24/apps - ${pkgs.buildPackages.imagemagick}/bin/convert \ - ${../../../assets/ghaf-logo.png} \ - -resize 24x24 \ - $out/share/icons/hicolor/24x24/apps/ghaf-icon-24x24.png - ''; + launchpad-icon = svgToPNG "launchpad" ../../../assets/icons/svg/launchpad.svg "38x38"; + admin-icon = svgToPNG "admin" ../../../assets/icons/svg/admin-cog.svg "24x24"; + ghaf-icon = svgToPNG "ghaf-white" ../../../assets/icons/svg/ghaf-white.svg "24x24"; wifiDevice = lib.lists.findFirst (d: d.name != null) null networkDevice; wifi-signal-strength = pkgs.callPackage ../../../packages/wifi-signal-strength {wifiDevice = wifiDevice.name;}; @@ -38,11 +35,18 @@ in { # Modified from default waybar configuration file https://github.com/Alexays/Waybar/blob/master/resources/config '' { - "height": 30, // Waybar height (to be removed for auto height) + "height": 48, // Waybar height "spacing": 4, // Gaps between modules (4px) - "modules-left": ["custom/launcher"], + "modules-left": ["custom/launchpad", "custom/ghaf-settings"], "modules-center": ["sway/window"], - "modules-right": ["pulseaudio", "custom/network1", "backlight", "battery", "clock", "tray"], + "position": "bottom", + "mode": "dock", + "spacing": 4, + "margin-top": 3, + "margin-bottom": 5, + "margin-left": 200, + "margin-right": 200, + "modules-right": ["pulseaudio", "custom/network1", "battery", "custom/admin", "clock", "tray"], "keyboard-state": { "numlock": true, "capslock": true, @@ -91,11 +95,22 @@ in { }, '' + '' - "custom/launcher": { + "custom/launchpad": { "format": " ", "on-click": "${ghaf-launcher}/bin/ghaf-launcher", "tooltip": false }, + "custom/ghaf-settings": { + "format": " ", + // Placeholder for the actual Ghaf settings app + "on-click": "${pkgs.libnotify}/bin/notify-send 'Ghaf Platform ${lib.strings.fileContents ../../../.version}'", + "tooltip": false + }, + "custom/admin": { + "format": " ", + "on-click": "${pkgs.nm-launcher}/bin/nm-launcher", + "tooltip": false + }, "pulseaudio": { // "scroll-step": 1, // %, can be a float "format": "{volume}% {icon} {format_source}", @@ -119,13 +134,14 @@ in { # Modified from default waybar style file https://github.com/Alexays/Waybar/blob/master/resources/style.css '' * { - font-family: FontAwesome, Inter, Roboto, sans-serif; - font-size: 14px; + font-family: FontAwesome, Inter, sans-serif; + font-size: 16px; + border: none; + border-radius: 5px; } window#waybar { - background-color: rgba(43, 48, 59, 0.5); - border-bottom: 3px solid rgba(100, 114, 125, 0.5); + background-color: rgba(32, 32, 32, 0.9); color: #ffffff; transition-property: background-color; transition-duration: .5s; @@ -166,24 +182,22 @@ in { } #workspaces button.focused { - background-color: #64727D; box-shadow: inset 0 -3px #ffffff; } - #workspaces button.urgent { - background-color: #eb4d4b; - } #clock, #battery, #backlight, #custom-network1, - #custom-launcher, + #custom-launchpad, + #custom-ghaf-settings, + #custom-admin, #pulseaudio, #tray, #window, #workspaces { - margin: 0 4px; + padding: 0 20px; } .modules-left > widget:first-child > #workspaces { @@ -194,112 +208,43 @@ in { margin-right: 0; } + #pulseaudio, + #custom-network1, + #backlight, + #battery, #clock { - background-color: #64727D; - padding-left: 10; - padding-right: 10; - } - - #battery { - background-color: #ffffff; - color: #000000; padding-left: 10; padding-right: 10; } - #battery.charging, #battery.plugged { - color: #ffffff; - background-color: #26A65B; - } - - @keyframes blink { - to { - background-color: #ffffff; - color: #000000; - } - } - - #battery.critical:not(.charging) { - background-color: #f53c3c; - color: #ffffff; - animation-name: blink; - animation-duration: 0.5s; - animation-timing-function: linear; - animation-iteration-count: infinite; - animation-direction: alternate; - } - label:focus { background-color: #000000; } - #backlight { - background-color: #90b1b1; - padding-left: 10; - padding-right: 10; - } - - #custom-network1 { - background-color: #2980b9; - min-width: 16px; - padding-left: 10; - padding-right: 10; - } - - #custom-network1.disconnected { - background-color: #f53c3c; - } - - #pulseaudio { - background-color: #f1c40f; - color: #000000; - padding-left: 10; - padding-right: 10; - } - - #pulseaudio.muted { - background-color: #90b1b1; - color: #2a5c45; - } - - #tray { - background-color: #2980b9; - } - #tray > .passive { -gtk-icon-effect: dim; } - #tray > .needs-attention { - -gtk-icon-effect: highlight; - background-color: #eb4d4b; - } - - #language { - background: #00b093; - color: #740864; - padding: 0 5px; - margin: 0 5px; - min-width: 16px; - } - - #keyboard-state { - background: #97e1ad; - color: #000000; - padding: 0 0px; - margin: 0 5px; - min-width: 16px; + #custom-launchpad { + font-size: 20px; + background-image: url("${launchpad-icon}"); + background-position: center; + background-repeat: no-repeat; + margin-left: 13px; } - #keyboard-state > label { - padding: 0 5px; + #custom-ghaf-settings { + font-size: 20px; + background-image: url("${ghaf-icon}"); + background-position: center; + background-repeat: no-repeat; + padding-left: 10; + padding-right: 10; } - #keyboard-state > label.locked { - background: rgba(0, 0, 0, 0.2); - } - #custom-launcher { - font-size: 20px; background-image: url("${ghaf-icon}/share/icons/hicolor/24x24/apps/ghaf-icon-24x24.png"); + #custom-admin { + font-size: 20px; + background-image: url("${admin-icon}"); background-position: center; background-repeat: no-repeat; padding-left: 10; diff --git a/overlays/custom-packages/waypipe/waypipe-window-borders.patch b/overlays/custom-packages/waypipe/waypipe-window-borders.patch index c2968a309c..177ad0ac5e 100644 --- a/overlays/custom-packages/waypipe/waypipe-window-borders.patch +++ b/overlays/custom-packages/waypipe/waypipe-window-borders.patch @@ -329,7 +329,7 @@ index 1c1be71..61e2200 100644 + .border_color = { + .a = 255, .r = 0, .g = 0, .b = 0 + }, -+ .border_size = 5}; ++ .border_size = 3}; /* We do not parse any getopt arguments happening after the mode choice * string, so as not to interfere with them. */ diff --git a/targets/lenovo-x1/appvms/chromium.nix b/targets/lenovo-x1/appvms/chromium.nix index 8caaf9319a..f1fbaf13bf 100644 --- a/targets/lenovo-x1/appvms/chromium.nix +++ b/targets/lenovo-x1/appvms/chromium.nix @@ -63,5 +63,5 @@ in { xdg.mime.defaultApplications."application/pdf" = "ghaf-pdf.desktop"; } ]; - borderColor = "#ff5733"; + borderColor = "#630505"; } diff --git a/targets/lenovo-x1/appvms/gala.nix b/targets/lenovo-x1/appvms/gala.nix index 20aff4be12..4371d790bd 100644 --- a/targets/lenovo-x1/appvms/gala.nix +++ b/targets/lenovo-x1/appvms/gala.nix @@ -12,5 +12,5 @@ time.timeZone = "Asia/Dubai"; } ]; - borderColor = "#33ff57"; + borderColor = "#027d7b"; } diff --git a/targets/lenovo-x1/appvms/zathura.nix b/targets/lenovo-x1/appvms/zathura.nix index d2ca18710f..61d1d68f0f 100644 --- a/targets/lenovo-x1/appvms/zathura.nix +++ b/targets/lenovo-x1/appvms/zathura.nix @@ -12,5 +12,5 @@ time.timeZone = "Asia/Dubai"; } ]; - borderColor = "#337aff"; + borderColor = "#122263"; }