feat(hyprland): session Hyprland en test à côté d'i3
- Hyprland via UWSM (comme Omarchy), à choisir à la connexion ; i3 reste la session par défaut - config Lua (format Hyprland >= 0.55) : raccourcis bépo d'i3, apparence Omarchy, Ghostty comme terminal - waybar, hyprlock, swaybg, grim/slurp, wl-clipboard, brightnessctl - workspace-run : support de hyprctl et des options en --opt= - stt-dictate : wtype sous Wayland au lieu de xdotool Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ac6ae897f4
commit
967a31d574
@@ -11,7 +11,7 @@ NixOS dotfiles for Pierre MARTIN (Lundi Matin — Front-Commerce, LMB, NEIA), us
|
|||||||
- `nixos/configuration.nix` — System-level NixOS config (bootloader, networking, services, system packages). Imports `hardware-configuration.nix` et `framework.nix`.
|
- `nixos/configuration.nix` — System-level NixOS config (bootloader, networking, services, system packages). Imports `hardware-configuration.nix` et `framework.nix`.
|
||||||
- `home.nix` — Entry point home-manager. Importe `packages.nix` et les modules de `programs/`. Mappe aussi les fichiers statiques depuis `files/`.
|
- `home.nix` — Entry point home-manager. Importe `packages.nix` et les modules de `programs/`. Mappe aussi les fichiers statiques depuis `files/`.
|
||||||
- `packages.nix` — Tous les packages utilisateur (avec allowlist unfree).
|
- `packages.nix` — Tous les packages utilisateur (avec allowlist unfree).
|
||||||
- `programs/` — Modules home-manager par programme : `git.nix`, `zsh.nix`, `i3.nix`, `neia.nix`.
|
- `programs/` — Modules home-manager par programme : `git.nix`, `zsh.nix`, `i3.nix`, `hyprland.nix`, `ghostty.nix`, `neovim.nix`, `pi.nix`.
|
||||||
- `files/` — Fichiers de config statiques copiés dans `$HOME` par home-manager (`.npmrc`, `traefik.toml`, etc.).
|
- `files/` — Fichiers de config statiques copiés dans `$HOME` par home-manager (`.npmrc`, `traefik.toml`, etc.).
|
||||||
|
|
||||||
Home-manager est intégré au module NixOS (pas standalone). Appliquer avec `sudo nixos-rebuild switch`.
|
Home-manager est intégré au module NixOS (pas standalone). Appliquer avec `sudo nixos-rebuild switch`.
|
||||||
@@ -46,7 +46,7 @@ Après modification de fichiers `.sh`, lancer `make fmt && make lint` avant d'ap
|
|||||||
## Key details
|
## Key details
|
||||||
|
|
||||||
- Keyboard layout : bépo (`fr` variant `bepo`)
|
- Keyboard layout : bépo (`fr` variant `bepo`)
|
||||||
- Window manager : i3 (Mod4)
|
- Window manager : i3 (Mod4), session par défaut. Hyprland (Wayland, config Lua dans `files/hypr/hyprland.lua`) en test, mêmes raccourcis bépo
|
||||||
- Shell : zsh + oh-my-zsh + starship + mcfly
|
- Shell : zsh + oh-my-zsh + starship + mcfly
|
||||||
- Terminal : sakura
|
- Terminal : sakura
|
||||||
- Git : difftastic (diffs), meld (merges), `push.autoSetupRemote = true`
|
- Git : difftastic (diffs), meld (merges), `push.autoSetupRemote = true`
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
-- Hyprland - https://wiki.hypr.land/Configuring/Start/
|
||||||
|
-- Raccourcis repris de programs/i3.nix (bépo), apparence reprise d'Omarchy :
|
||||||
|
-- https://github.com/basecamp/omarchy/tree/master/default/hypr
|
||||||
|
|
||||||
|
local mod = "SUPER"
|
||||||
|
|
||||||
|
local function bind(keys, dispatcher, options)
|
||||||
|
if type(dispatcher) == "string" then
|
||||||
|
dispatcher = hl.dsp.exec_cmd(dispatcher)
|
||||||
|
end
|
||||||
|
hl.bind(keys, dispatcher, options or {})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Écrans : détection automatique (remplace autorandr)
|
||||||
|
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = "auto" })
|
||||||
|
|
||||||
|
hl.env("XCURSOR_SIZE", "24")
|
||||||
|
hl.env("GDK_BACKEND", "wayland,x11,*")
|
||||||
|
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
|
||||||
|
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "wayland")
|
||||||
|
hl.env("TERMINAL", "ghostty")
|
||||||
|
|
||||||
|
hl.config({
|
||||||
|
input = {
|
||||||
|
kb_layout = "fr",
|
||||||
|
kb_variant = "bepo",
|
||||||
|
follow_mouse = 1,
|
||||||
|
repeat_rate = 40,
|
||||||
|
repeat_delay = 250,
|
||||||
|
numlock_by_default = true,
|
||||||
|
touchpad = {
|
||||||
|
clickfinger_behavior = true,
|
||||||
|
scroll_factor = 0.4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
general = {
|
||||||
|
gaps_in = 5,
|
||||||
|
gaps_out = 10,
|
||||||
|
border_size = 2,
|
||||||
|
col = {
|
||||||
|
active_border = { colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 },
|
||||||
|
inactive_border = "rgba(595959aa)",
|
||||||
|
},
|
||||||
|
resize_on_border = true,
|
||||||
|
layout = "dwindle",
|
||||||
|
},
|
||||||
|
|
||||||
|
decoration = {
|
||||||
|
rounding = 0,
|
||||||
|
shadow = { enabled = false },
|
||||||
|
blur = { enabled = false },
|
||||||
|
},
|
||||||
|
|
||||||
|
animations = { enabled = true },
|
||||||
|
|
||||||
|
dwindle = {
|
||||||
|
preserve_split = true,
|
||||||
|
force_split = 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
misc = {
|
||||||
|
disable_hyprland_logo = true,
|
||||||
|
disable_splash_rendering = true,
|
||||||
|
background_color = "rgb(000000)",
|
||||||
|
focus_on_activate = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Remplace unclutter
|
||||||
|
cursor = { inactive_timeout = 3 },
|
||||||
|
})
|
||||||
|
|
||||||
|
hl.on("hyprland.start", function()
|
||||||
|
hl.exec_cmd("waybar")
|
||||||
|
hl.exec_cmd("swaybg --mode fill --image /home/pierre/Documents/Graphisme/fc-bg-light-black.png")
|
||||||
|
hl.exec_cmd("copyq")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Applications
|
||||||
|
bind(mod .. " + Return", "~/.local/bin/workspace-run ghostty --working-directory=")
|
||||||
|
bind(mod .. " + SHIFT + Return", "~/.local/bin/workspace-run code")
|
||||||
|
bind(mod .. " + d", "rofi -combi-modi 'window#run#ssh#emoji#calc' -modi 'calc#combi' -show combi")
|
||||||
|
bind(mod .. " + space", "~/.local/bin/stt-dictate toggle")
|
||||||
|
bind(mod .. " + SHIFT + t", "hyprlock")
|
||||||
|
bind("Print", "grim -g \"$(slurp)\" - | wl-copy")
|
||||||
|
bind("SHIFT + Print", "grim - | wl-copy")
|
||||||
|
|
||||||
|
-- Fenêtres (mêmes touches qu'i3 en bépo)
|
||||||
|
bind(mod .. " + b", hl.dsp.window.close())
|
||||||
|
bind(mod .. " + e", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
|
||||||
|
bind(mod .. " + p", hl.dsp.layout("togglesplit"))
|
||||||
|
-- Pas de layout tabbed/stacking dans Hyprland : les groupes en sont l'équivalent
|
||||||
|
bind(mod .. " + eacute", hl.dsp.group.toggle())
|
||||||
|
bind(mod .. " + u", hl.dsp.group.next())
|
||||||
|
bind(mod .. " + SHIFT + space", hl.dsp.window.float({ action = "toggle" }))
|
||||||
|
|
||||||
|
for _, arrow in ipairs({ { "Left", "l" }, { "Right", "r" }, { "Up", "u" }, { "Down", "d" } }) do
|
||||||
|
local key, direction = arrow[1], arrow[2]
|
||||||
|
bind(mod .. " + " .. key, hl.dsp.focus({ direction = direction }))
|
||||||
|
bind(mod .. " + SHIFT + " .. key, hl.dsp.window.swap({ direction = direction }))
|
||||||
|
bind(mod .. " + CTRL + " .. key, hl.dsp.workspace.move({ monitor = direction }))
|
||||||
|
end
|
||||||
|
|
||||||
|
bind(mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
||||||
|
bind(mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
||||||
|
|
||||||
|
-- Espaces de travail : keycodes 10 à 19 = rangée du haut, quelle que soit la
|
||||||
|
-- disposition (" « » ( ) @ + - / * en bépo)
|
||||||
|
for workspace = 1, 10 do
|
||||||
|
local key = "code:" .. tostring(workspace + 9)
|
||||||
|
bind(mod .. " + " .. key, hl.dsp.focus({ workspace = tostring(workspace) }))
|
||||||
|
bind(mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = tostring(workspace) }))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Session
|
||||||
|
bind(mod .. " + SHIFT + c", "hyprctl reload")
|
||||||
|
bind(mod .. " + SHIFT + e", "uwsm stop")
|
||||||
|
|
||||||
|
-- Touches multimédia (actives même écran verrouillé)
|
||||||
|
local media = { locked = true, repeating = true }
|
||||||
|
bind("XF86AudioRaiseVolume", "pactl set-sink-volume @DEFAULT_SINK@ +5%", media)
|
||||||
|
bind("XF86AudioLowerVolume", "pactl set-sink-volume @DEFAULT_SINK@ -5%", media)
|
||||||
|
bind("XF86AudioMute", "pactl set-sink-mute @DEFAULT_SINK@ toggle", { locked = true })
|
||||||
|
bind("XF86AudioPlay", "playerctl play-pause", { locked = true })
|
||||||
|
bind("XF86AudioPause", "playerctl play-pause", { locked = true })
|
||||||
|
bind("XF86AudioNext", "playerctl next", { locked = true })
|
||||||
|
bind("XF86AudioPrev", "playerctl previous", { locked = true })
|
||||||
|
bind("XF86MonBrightnessUp", "brightnessctl set +5%", media)
|
||||||
|
bind("XF86MonBrightnessDown", "brightnessctl set 5%-", media)
|
||||||
@@ -86,7 +86,11 @@ stop_and_transcribe() {
|
|||||||
# Tape le texte au curseur
|
# Tape le texte au curseur
|
||||||
if [[ -n "$TEXT" ]]; then
|
if [[ -n "$TEXT" ]]; then
|
||||||
sleep 0.1 # petit delai pour focus
|
sleep 0.1 # petit delai pour focus
|
||||||
xdotool type --delay 10 -- "$TEXT"
|
if [[ -n "${WAYLAND_DISPLAY:-}" ]]; then
|
||||||
|
wtype -d 10 -- "$TEXT"
|
||||||
|
else
|
||||||
|
xdotool type --delay 10 -- "$TEXT"
|
||||||
|
fi
|
||||||
notify "$TEXT"
|
notify "$TEXT"
|
||||||
else
|
else
|
||||||
notify "Aucun texte detecte"
|
notify "Aucun texte detecte"
|
||||||
|
|||||||
+24
-6
@@ -3,22 +3,35 @@
|
|||||||
# Examples:
|
# Examples:
|
||||||
# workspace-run.sh zeditor
|
# workspace-run.sh zeditor
|
||||||
# workspace-run.sh sakura --working-directory
|
# workspace-run.sh sakura --working-directory
|
||||||
|
# workspace-run.sh ghostty --working-directory= (un argument finissant par = est collé au dossier)
|
||||||
cmd=${1:?usage: workspace-run.sh <command> [args...]}
|
cmd=${1:?usage: workspace-run.sh <command> [args...]}
|
||||||
shift
|
shift
|
||||||
|
|
||||||
workspace=$(i3-msg -t get_workspaces | jq -r '.[] | select(.focused) | .name')
|
if [ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]; then
|
||||||
|
workspace=$(hyprctl activeworkspace -j | jq -r '.name')
|
||||||
|
else
|
||||||
|
workspace=$(i3-msg -t get_workspaces | jq -r '.[] | select(.focused) | .name')
|
||||||
|
fi
|
||||||
|
|
||||||
|
window_pids() {
|
||||||
|
if [ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]; then
|
||||||
|
hyprctl clients -j | jq -r --arg ws "$workspace" '.[] | select(.workspace.name == $ws) | .pid'
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
terminal_cwd() {
|
|
||||||
local wids
|
local wids
|
||||||
wids=$(i3-msg -t get_tree | jq -r "
|
wids=$(i3-msg -t get_tree | jq -r "
|
||||||
.nodes[].nodes[].nodes[]
|
.nodes[].nodes[].nodes[]
|
||||||
| select(.name == \"$workspace\")
|
| select(.name == \"$workspace\")
|
||||||
| .. | objects | select(.window? != null) | .window
|
| .. | objects | select(.window? != null) | .window
|
||||||
")
|
")
|
||||||
|
|
||||||
for wid in $wids; do
|
for wid in $wids; do
|
||||||
local pid
|
xdotool getwindowpid "$wid" 2>/dev/null
|
||||||
pid=$(xdotool getwindowpid "$wid" 2>/dev/null) || continue
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
terminal_cwd() {
|
||||||
|
for pid in $(window_pids); do
|
||||||
local shell_pid
|
local shell_pid
|
||||||
shell_pid=$(pgrep -P "$pid" -x zsh | head -1) || continue
|
shell_pid=$(pgrep -P "$pid" -x zsh | head -1) || continue
|
||||||
local cwd
|
local cwd
|
||||||
@@ -35,4 +48,9 @@ if [ -z "$dir" ]; then
|
|||||||
dir=$(grep "^${workspace}=" "$dir_file" 2>/dev/null | cut -d= -f2-)
|
dir=$(grep "^${workspace}=" "$dir_file" 2>/dev/null | cut -d= -f2-)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$cmd" "$@" "${dir:-$HOME}"
|
dir=${dir:-$HOME}
|
||||||
|
if [ $# -gt 0 ] && [[ "${!#}" == *= ]]; then
|
||||||
|
set -- "${@:1:$#-1}" "${!#}$dir"
|
||||||
|
exec "$cmd" "$@"
|
||||||
|
fi
|
||||||
|
exec "$cmd" "$@" "$dir"
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
./programs/ghostty.nix
|
./programs/ghostty.nix
|
||||||
./programs/git.nix
|
./programs/git.nix
|
||||||
|
./programs/hyprland.nix
|
||||||
./programs/i3.nix
|
./programs/i3.nix
|
||||||
./programs/neovim.nix
|
./programs/neovim.nix
|
||||||
./programs/pi.nix
|
./programs/pi.nix
|
||||||
|
|||||||
@@ -86,6 +86,14 @@
|
|||||||
defaultSession = "none+i3";
|
defaultSession = "none+i3";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Session Hyprland en test : à choisir sur l'écran de connexion.
|
||||||
|
# UWSM, comme Omarchy, lance les services de session (graphical-session.target).
|
||||||
|
programs.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
withUWSM = true;
|
||||||
|
};
|
||||||
|
security.pam.services.hyprlock = { };
|
||||||
|
|
||||||
# Configure console keymap
|
# Configure console keymap
|
||||||
console.keyMap = "fr";
|
console.keyMap = "fr";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
# Session Hyprland, en test à côté d'i3. Le compositeur et la session sont
|
||||||
|
# activés côté système (programs.hyprland dans nixos/configuration.nix).
|
||||||
|
{
|
||||||
|
xdg.configFile."hypr/hyprland.lua".source = ../files/hypr/hyprland.lua;
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
swaybg # fond d'écran (remplace feh)
|
||||||
|
grim # captures d'écran…
|
||||||
|
slurp # … d'une zone
|
||||||
|
wl-clipboard # wl-copy / wl-paste (remplace xsel)
|
||||||
|
wtype # saisie de texte (remplace xdotool), pour stt-dictate
|
||||||
|
brightnessctl # remplace xbacklight
|
||||||
|
];
|
||||||
|
|
||||||
|
# Lancée par hyprland.lua et pas par systemd, pour ne pas apparaître sous i3
|
||||||
|
programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
settings.main = {
|
||||||
|
layer = "top";
|
||||||
|
position = "top";
|
||||||
|
height = 26;
|
||||||
|
modules-left = [ "hyprland/workspaces" ];
|
||||||
|
modules-center = [ "clock" ];
|
||||||
|
modules-right = [
|
||||||
|
"cpu"
|
||||||
|
"temperature"
|
||||||
|
"disk"
|
||||||
|
"network"
|
||||||
|
"pulseaudio"
|
||||||
|
"battery"
|
||||||
|
"tray"
|
||||||
|
];
|
||||||
|
clock = {
|
||||||
|
format = "{:%a %d %b %H:%M}";
|
||||||
|
tooltip-format = "<tt>{calendar}</tt>";
|
||||||
|
};
|
||||||
|
cpu.format = "CPU {usage}%";
|
||||||
|
disk.format = "/ {percentage_used}%";
|
||||||
|
network = {
|
||||||
|
format-wifi = "{essid} {signalStrength}%";
|
||||||
|
format-ethernet = "{ipaddr}";
|
||||||
|
format-disconnected = "hors ligne";
|
||||||
|
};
|
||||||
|
pulseaudio = {
|
||||||
|
format = "vol {volume}%";
|
||||||
|
format-muted = "muet";
|
||||||
|
on-click = "pavucontrol";
|
||||||
|
};
|
||||||
|
battery.format = "bat {capacity}%";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.hyprlock = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
general.hide_cursor = true;
|
||||||
|
background = [
|
||||||
|
{
|
||||||
|
color = "rgb(000000)";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
input-field = [
|
||||||
|
{
|
||||||
|
size = "400, 60";
|
||||||
|
position = "0, 0";
|
||||||
|
halign = "center";
|
||||||
|
valign = "center";
|
||||||
|
placeholder_text = "Mot de passe";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user