Compare commits

..

2 commits

Author SHA1 Message Date
0e7f2ada72
fix(jade): resolve Thunar 20s startup delay
Import DISPLAY and XAUTHORITY into systemd user environment and restart
xdg-desktop-portal-gtk service in xinitrc. This fixes the issue where
portal backends fail to start with "cannot open display" error when using
startx instead of a display manager.

Without this, Thunar waits 25 seconds for org.freedesktop.portal.Desktop
to respond before timing out and displaying.
2025-12-21 12:51:17 +08:00
4169045fa4
feat(jade): create modular desktop environment
Rename xmonad/ to jade/ and restructure as a complete desktop environment
with hybrid NixOS and home-manager modules. This establishes jade as a
self-contained, gruvbox-themed DE that can eventually be extracted as a flake.

Changes:
- Create jade/ with NixOS module (WM, system packages, GTK theme)
- Create jade/home.nix for home-manager services (wezterm, picom, dunst)
- Move dmenu with gruvbox patches into jade/dmenu/
- Convert wezterm to pure Lua config with gruvbox-material colors
- Move xinitrc into jade/ directory
- Remove feh/scrot from global env (now in jade)
- Remove dmenu overlay from global overlays
- Simplify home-manager desktop features to just user apps

This follows the pattern of real DEs (GNOME, KDE) where system and user
configs are split across NixOS and home-manager modules.
2025-12-21 12:36:11 +08:00
19 changed files with 316 additions and 200 deletions

View file

@ -1,4 +1,8 @@
{pkgs, config, ...}: {
{
pkgs,
config,
...
}: {
imports = [
./direnv.nix
./starship.nix
@ -47,10 +51,25 @@
];
# Extra commands that should be added to '.zshrc'
initContent = ''
initContent = /* sh */ ''
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
export PATH
# Auto-set wezterm tab title based on directory
chpwd() {
if [[ -d .git ]]; then
# Use git repo name
local repo=$(basename $(git rev-parse --show-toplevel 2>/dev/null))
wezterm cli set-tab-title "$repo" 2>/dev/null
elif [[ $(pwd) =~ "/home/sajenim/.repositories/personal/([^/]+)" ]]; then
# Use directory name for project dirs
wezterm cli set-tab-title "''${match[1]}" 2>/dev/null
fi
}
# Run once on shell startup
chpwd
'';
};
}

View file

@ -1,15 +1,8 @@
{
inputs,
pkgs,
...
}: {
{pkgs, ...}: {
imports = [
./cava
./dunst
./mpv
./obs
./picom
./wezterm
];
# Install some packages for our desktop environment
@ -22,26 +15,4 @@
# KDE Packages
kdePackages.kdenlive
];
home.file = {
# Install patched fonts
".local/share/fonts" = {
recursive = true;
source = "${inputs.self}/pkgs/patched-fonts";
};
# https://www.sainnhe.dev/post/patch-fonts-with-cursive-italic-styles/
# Configure the initialization of xinit
".xinitrc".source = ./xinitrc;
};
# Configure GTK 2/3 applications to use gruvbox-material
gtk = {
enable = true;
theme = {
name = "Gruvbox-Material-Dark";
package = pkgs.unstable.gruvbox-material-gtk-theme;
};
iconTheme.name = "Gruvbox-Material-Dark";
};
}

View file

@ -1,50 +0,0 @@
{pkgs, ...}: {
programs.wezterm = {
enable = true;
package = pkgs.unstable.wezterm;
# Enable our shell integrations
enableZshIntegration = true;
# Install our theme
colorSchemes = {
gruvbox_material_dark_medium = {
background = "#282828"; # bg0
foreground = "#D4BE98"; # fg0
selection_bg = "#3C3836"; # bg_current_word
selection_fg = "#A89984"; # grey2
cursor_bg = "#A89984"; # bg_current_word
cursor_fg = "#3C3836"; # grey2
cursor_border = "#A89984"; # grey2
ansi = [
"#282828" # bg0
"#EA6962" # red
"#A9B665" # green
"#D8A657" # yellow
"#7DAEA3" # blue
"#D3869B" # purple
"#89B482" # aqua
"#D4BE98" # fg0
];
brights = [
"#7C6F65" # grey0
"#EA6962" # red
"#A9B665" # green
"#D8A657" # yellow
"#7DAEA3" # blue
"#D3869B" # purple
"#89B482" # aqua
"#DDC7A1" # fg1
];
};
# https://github.com/sainnhe/gruvbox-material
};
# Load our wezterm configuration
extraConfig = builtins.readFile ./wezterm.lua;
};
}

View file

@ -1,22 +0,0 @@
#/bin/bash
# Setup our monitors
xrandr --output HDMI-A-0 --mode 1920x1080 --output DisplayPort-0 --mode 2560x1440 --right-of HDMI-A-0
# Apply our wallpaper
feh --bg-center ~/.repositories/personal/nix-config/assets/chinatown.png
# Disable screen saver and DPMS features
xset s off -dpms
# Start our notification daemon
dunst &
# Enable our compositor
picom -b
# Fix for pinentry bug on NixOS
gpgconf --reload gpg-agent
# Launch our window manager
exec xmonad

View file

@ -1,6 +1,12 @@
{...}: {
{inputs, ...}: {
imports = [
# Global home-manager configuration
./global
# Desktop environment (wezterm, picom, dunst, xinitrc)
"${inputs.self}/nixos/common/users/sajenim/jade/home.nix"
# Optional user features and applications
./features/cli
./features/desktop
./features/editors

View file

@ -22,9 +22,6 @@
# File Management
fd ranger tree
# Graphics & Screenshots
feh scrot
# Networking
curl nmap sshfs wget

View file

@ -0,0 +1,88 @@
{
pkgs,
inputs,
...
}: {
imports = [
./dmenu
];
# Desktop environment packages and configuration
environment = {
systemPackages = [
# Required for some XFCE/GTK stuff
pkgs.dconf
# Picture viewer
pkgs.xfce.ristretto
# Wallpaper setter
pkgs.feh
# Screenshot tool
pkgs.scrot
# GTK theme
pkgs.unstable.gruvbox-material-gtk-theme
# Install our XMonad and Xmobar configuration
inputs.xmonad-config.packages.${pkgs.stdenv.hostPlatform.system}.default
];
# Set default terminal for the desktop environment
sessionVariables = {
TERMINAL = "wezterm";
};
};
# Programs and tools for the desktop environment
programs = {
# File browser
thunar.enable = true;
# Configuration storage system for xfce
xfconf.enable = true;
# Enable dconf for GTK applications
dconf.enable = true;
};
# System services for the desktop environment
services = {
# Mount, trash, and other functionalities
gvfs.enable = true;
# Thumbnail support for images
tumbler.enable = true;
};
# XDG desktop portal for file pickers, screen sharing, etc.
xdg.portal = {
enable = true;
config.common.default = ["gtk"];
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
xdg-desktop-portal-wlr
];
};
# Install patched fonts for the desktop environment
fonts.packages = [
(pkgs.stdenv.mkDerivation {
name = "jade-fonts";
src = "${inputs.self}/pkgs/patched-fonts";
installPhase = ''
mkdir -p $out/share/fonts
cp -r $src/* $out/share/fonts/
'';
})
];
# Configure GTK theme system-wide
environment.etc = {
"xdg/gtk-3.0/settings.ini".text = /* ini */ ''
[Settings]
gtk-theme-name=Gruvbox-Material-Dark
gtk-icon-theme-name=Gruvbox-Material-Dark
gtk-application-prefer-dark-theme=true
'';
"xdg/gtk-4.0/settings.ini".text = /* ini */ ''
[Settings]
gtk-theme-name=Gruvbox-Material-Dark
gtk-icon-theme-name=Gruvbox-Material-Dark
gtk-application-prefer-dark-theme=true
'';
};
}

View file

@ -0,0 +1,15 @@
{pkgs, ...}: {
# Dynamic menu for X with gruvbox theme and custom bar height
nixpkgs.overlays = [
(final: prev: {
dmenu = prev.dmenu.overrideAttrs (oldAttrs: {
patches = [
./patches/dmenu-bar-height-5.2.diff
./patches/dmenu-gruvbox-20210329-9ae8ea5.diff
];
});
})
];
environment.systemPackages = [pkgs.dmenu];
}

View file

@ -0,0 +1,27 @@
diff --git a/config.def.h b/config.def.h
index 1edb647..5c79628 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,8 @@
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
/* -fn option overrides fonts[0]; default X11 font or font set */
+static const int user_bh = 7; /* add an defined amount of pixels to the bar height */
+
static const char *fonts[] = {
"monospace:size=10"
};
diff --git a/dmenu.c b/dmenu.c
index 27b7a30..7be0dc3 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -629,7 +629,8 @@ setup(void)
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
/* calculate menu geometry */
- bh = drw->fonts->h + 2;
+ bh = drw->fonts->h;
+ bh = user_bh ? bh + user_bh : bh + 2;
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
#ifdef XINERAMA

View file

@ -0,0 +1,28 @@
From 9ae8ea55988973aa19f1e069ee24ba7af5a669e0 Mon Sep 17 00:00:00 2001
From: Miles Glapa-Grossklag <m.glapa.grossklag@gmail.com>
Date: Mon, 29 Mar 2021 18:57:52 -0700
Subject: [PATCH] Add gruvbox dark colorscheme
---
config.def.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1edb647..36105e5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -9,9 +9,9 @@ static const char *fonts[] = {
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const char *colors[SchemeLast][2] = {
/* fg bg */
- [SchemeNorm] = { "#bbbbbb", "#222222" },
- [SchemeSel] = { "#eeeeee", "#005577" },
- [SchemeOut] = { "#000000", "#00ffff" },
+ [SchemeNorm] = { "#a89984", "#282828" },
+ [SchemeSel] = { "#32302f", "#a9b665" },
+ [SchemeOut] = { "#a89984", "#89b482" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
--
2.25.1

View file

@ -1,4 +1,5 @@
{...}: {
# Notification daemon
services.dunst = {
enable = true;
settings = {
@ -11,17 +12,14 @@
frame_color = "#32302f";
corner_radius = 10;
};
urgency_low = {
background = "#282828";
foreground = "#d4be98";
};
urgency_normal = {
background = "#282828";
foreground = "#d4be98";
};
urgency_critical = {
background = "#282828";
foreground = "#d4be98";

View file

@ -0,0 +1,24 @@
{
pkgs,
inputs,
...
}: {
imports = [
./dunst
./picom
];
# Wezterm terminal emulator with jade configuration
programs.wezterm = {
enable = true;
package = pkgs.unstable.wezterm;
enableZshIntegration = true;
extraConfig = builtins.readFile (
"${inputs.self}/nixos/common/users/sajenim/jade/wezterm.lua"
);
};
# X session initialization script
home.file.".xinitrc".source =
"${inputs.self}/nixos/common/users/sajenim/jade/xinitrc";
}

View file

@ -1,10 +1,9 @@
{...}: {
# X11 compositor for transparency and effects
services.picom = {
enable = true;
shadow = true;
shadowExclude = [
"class_g = 'dmenu'"
];
shadowExclude = ["class_g = 'dmenu'"];
backend = "xrender";
};
}

View file

@ -4,6 +4,16 @@ local wezterm = require("wezterm")
-- Log warnings or generate errors if we define an invalid configuration option
local config = wezterm.config_builder()
-- Format window title to prefer explicit tab titles over process names
wezterm.on('format-window-title', function(tab, pane, tabs, panes, config)
-- Use explicit tab title if set, otherwise fall back to process name
if tab.tab_title and tab.tab_title ~= "" then
return tab.tab_title
end
-- Fallback to active pane's title (process name)
return tab.active_pane.title
end)
--
-- General configuration options.
--
@ -20,8 +30,38 @@ config.animation_fps = 144
config.font = wezterm.font("Fisa Code")
config.font_size = 10.0
-- Enable gruvbox colour scheme
config.color_scheme = "gruvbox_material_dark_medium"
-- Gruvbox Material Dark color scheme
config.colors = {
foreground = "#D4BE98",
background = "#282828",
cursor_bg = "#A89984",
cursor_fg = "#3C3836",
cursor_border = "#A89984",
selection_fg = "#A89984",
selection_bg = "#3C3836",
ansi = {
"#282828", -- black (bg0)
"#EA6962", -- red
"#A9B665", -- green
"#D8A657", -- yellow
"#7DAEA3", -- blue
"#D3869B", -- purple
"#89B482", -- aqua
"#D4BE98", -- white (fg0)
},
brights = {
"#7C6F65", -- bright black (grey0)
"#EA6962", -- bright red
"#A9B665", -- bright green
"#D8A657", -- bright yellow
"#7DAEA3", -- bright blue
"#D3869B", -- bright purple
"#89B482", -- bright aqua
"#DDC7A1", -- bright white (fg1)
},
}
-- Pad window borders
config.window_padding = {
@ -40,39 +80,37 @@ config.use_fancy_tab_bar = false
config.tab_max_width = 32
-- Tab bar colors
config.colors = {
tab_bar = {
background = "#32302f",
active_tab = {
bg_color = "#32302f",
fg_color = "#7daea3",
intensity = "Bold",
italic = true,
},
inactive_tab = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
inactive_tab_hover = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
new_tab = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
new_tab_hover = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
config.colors.tab_bar = {
background = "#32302f",
active_tab = {
bg_color = "#32302f",
fg_color = "#7daea3",
intensity = "Bold",
italic = true,
},
inactive_tab = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
inactive_tab_hover = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
new_tab = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
new_tab_hover = {
bg_color = "#32302f",
fg_color = "#a89984",
intensity = "Bold",
italic = true,
},
}
@ -197,7 +235,9 @@ config.key_tables = {
tab_mode = {
{ -- Create new tab
key = "n",
action = wezterm.action.SpawnTab("CurrentPaneDomain"),
action = wezterm.action.SpawnCommandInNewTab({
cwd = wezterm.home_dir,
}),
},
{ -- Close current tab
key = "q",

View file

@ -0,0 +1,23 @@
#!/bin/bash
# Setup monitors (machine-specific - consider making configurable)
xrandr --output HDMI-A-0 --mode 1920x1080 \
--output DisplayPort-0 --mode 2560x1440 --right-of HDMI-A-0
# Apply wallpaper
feh --bg-center ~/.repositories/personal/nix-config/assets/chinatown.png
# Disable screen saver and DPMS features
xset s off -dpms
# Fix for pinentry bug on NixOS
gpgconf --reload gpg-agent
# Import X display into systemd user environment
systemctl --user import-environment DISPLAY XAUTHORITY
# Start XDG desktop portal backend
systemctl --user restart xdg-desktop-portal-gtk.service
# Launch window manager
exec xmonad

View file

@ -1,35 +0,0 @@
{
pkgs,
inputs,
...
}: {
# Unfortunately some of these cannot be managed by
# home-manager, so we must install them to the system.
environment = {
systemPackages = [
# Required for some XFCE/GTK stuff
pkgs.dconf
# Dynamic menu for X
pkgs.dmenu
# Picture viewer
pkgs.xfce.ristretto
# Install our XMonad and Xmobar configuration
inputs.xmonad-config.packages.${pkgs.stdenv.hostPlatform.system}.default
];
};
programs = {
# File browser
thunar.enable = true;
# Configuration storage system for xfce
xfconf.enable = true;
};
services = {
# Mount, trash, and other functionalities
gvfs.enable = true;
# Thumbnail support for images
tumbler.enable = true;
};
}

View file

@ -6,7 +6,7 @@
# Our user configuration and optional user units
../common/users/sajenim
../common/users/sajenim/steam
../common/users/sajenim/xmonad
../common/users/sajenim/jade
# Optional components
../common/optional/yubikey.nix

View file

@ -1,10 +1,3 @@
{pkgs, ...}: {
# Required to install flatpak
xdg.portal = {
enable = true;
config.common.default = ["gtk"];
extraPortals = [pkgs.xdg-desktop-portal-wlr];
};
{...}: {
services.flatpak.enable = true;
}

View file

@ -7,12 +7,7 @@
# You can change versions, add patches, set compilation flags, anything really.
# https://nixos.wiki/wiki/Overlays
modifications = final: prev: {
dmenu = prev.dmenu.overrideAttrs (oldAttrs: {
patches = [
./patches/dmenu-bar-height-5.2.diff
./patches/dmenu-gruvbox-20210329-9ae8ea5.diff
];
});
# Currently empty - dmenu patches moved to jade
};
# When applied, the unstable nixpkgs set (declared in the flake inputs) will