Add MangoWM configuration and scripts for window management on scrolling layout
This commit is contained in:
@ -30,6 +30,11 @@
|
|||||||
inputs.home-manager.follows = "home-manager";
|
inputs.home-manager.follows = "home-manager";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mangowm = {
|
||||||
|
url = "github:mangowm/mango";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
stylix = {
|
stylix = {
|
||||||
url = "github:nix-community/stylix/master"; #Had to use branch or it would not build corrently
|
url = "github:nix-community/stylix/master"; #Had to use branch or it would not build corrently
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@ -79,6 +84,7 @@
|
|||||||
home-manager,
|
home-manager,
|
||||||
plasma-manager,
|
plasma-manager,
|
||||||
noctalia,
|
noctalia,
|
||||||
|
mangowm,
|
||||||
nixos-hardware,
|
nixos-hardware,
|
||||||
aagl,
|
aagl,
|
||||||
stylix,
|
stylix,
|
||||||
|
|||||||
20
mango/default.nix
Normal file
20
mango/default.nix
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
inputs.mangowm.nixosModules.mango
|
||||||
|
../modules/hyprlock
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
libnotify #Needed to send notifications myself (Like when reloading the config)
|
||||||
|
];
|
||||||
|
|
||||||
|
home-manager.sharedModules = [
|
||||||
|
./home.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.mango.enable = true;
|
||||||
|
}
|
||||||
208
mango/home.nix
Normal file
208
mango/home.nix
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
# ── External scripts ──
|
||||||
|
resizeScript = pkgs.writeShellScriptBin "resize.sh" (builtins.readFile ./scripts/resize.sh);
|
||||||
|
layoutCmdScript = pkgs.writeShellScriptBin "layout-cmd.sh" (builtins.readFile ./scripts/layout-cmd.sh);
|
||||||
|
|
||||||
|
# Helper to get the bin path
|
||||||
|
resizePath = "${resizeScript}/bin/resize.sh";
|
||||||
|
layoutCmdPath = "${layoutCmdScript}/bin/layout-cmd.sh";
|
||||||
|
|
||||||
|
tagBinds = lib.concatLists (
|
||||||
|
builtins.genList (i: let
|
||||||
|
n = toString (i + 1);
|
||||||
|
in [
|
||||||
|
"SUPER,${n},view,${n}"
|
||||||
|
"SUPER+CTRL,${n},tag,${n}"
|
||||||
|
])
|
||||||
|
9
|
||||||
|
);
|
||||||
|
|
||||||
|
# All key bindings
|
||||||
|
defaultBinds =
|
||||||
|
# --- Common/Session ---
|
||||||
|
[
|
||||||
|
"SUPER+SHIFT,E,quit"
|
||||||
|
#"SUPER+CTRL,R,reload_config"
|
||||||
|
"SUPER+CTRL,R,spawn_shell,mmsg dispatch reload_config && notify-send -u low -t 500 \"MangoWM\" \"Reloaded ✓\""
|
||||||
|
]
|
||||||
|
# --- Screenshot ---
|
||||||
|
++ [
|
||||||
|
"SUPER+SHIFT,S,spawn,noctalia msg screenshot-region"
|
||||||
|
]
|
||||||
|
# --- Launchers ---
|
||||||
|
++ [
|
||||||
|
"SUPER,T,spawn,kitty" # Mod+T → terminal
|
||||||
|
"SUPER,D,spawn,noctalia msg panel-toggle launcher" # Mod+D → launcher
|
||||||
|
#"SUPER+SHIFT,L,spawn,noctalia msg session lock" # Super+L → lock
|
||||||
|
"SUPER+SHIFT,L,spawn,hyprlock"
|
||||||
|
]
|
||||||
|
# --- Media keys ---
|
||||||
|
++ [
|
||||||
|
"NONE,XF86AudioRaiseVolume,spawn,noctalia msg volume-up"
|
||||||
|
"NONE,XF86AudioLowerVolume,spawn,noctalia msg volume-down"
|
||||||
|
"NONE,XF86AudioMute,spawn,noctalia msg volume-mute"
|
||||||
|
"NONE,XF86AudioMicMute,spawn,noctalia msg mic-mute"
|
||||||
|
"NONE,XF86AudioPlay,spawn,playerctl play-pause"
|
||||||
|
"NONE,XF86AudioStop,spawn,playerctl stop"
|
||||||
|
"NONE,XF86AudioPrev,spawn,playerctl previous"
|
||||||
|
"NONE,XF86AudioNext,spawn,playerctl next"
|
||||||
|
]
|
||||||
|
# --- Brightness ---
|
||||||
|
++ [
|
||||||
|
"NONE,XF86MonBrightnessUp,spawn,noctalia msg brightness-up"
|
||||||
|
"NONE,XF86MonBrightnessDown,spawn,noctalia msg brightness-down"
|
||||||
|
]
|
||||||
|
# --- Focus (directional) ---
|
||||||
|
++ [
|
||||||
|
"SUPER,Left,focusdir,left"
|
||||||
|
"SUPER,Down,focusdir,down"
|
||||||
|
"SUPER,Up,focusdir,up"
|
||||||
|
"SUPER,Right,focusdir,right"
|
||||||
|
# vim bindings
|
||||||
|
"SUPER,H,focusdir,left"
|
||||||
|
"SUPER,J,focusdir,down"
|
||||||
|
"SUPER,K,focusdir,up"
|
||||||
|
"SUPER,L,focusdir,right"
|
||||||
|
]
|
||||||
|
# --- Move windows (swap with neighbor) ---
|
||||||
|
++ [
|
||||||
|
"SUPER+CTRL,Left,exchange_client,left"
|
||||||
|
"SUPER+CTRL,Down,exchange_client,down"
|
||||||
|
"SUPER+CTRL,Up,exchange_client,up"
|
||||||
|
"SUPER+CTRL,Right,exchange_client,right"
|
||||||
|
# vim bindings
|
||||||
|
"SUPER+CTRL,H,exchange_client,left"
|
||||||
|
"SUPER+CTRL,J,exchange_client,down"
|
||||||
|
"SUPER+CTRL,K,exchange_client,up"
|
||||||
|
"SUPER+CTRL,L,exchange_client,right"
|
||||||
|
]
|
||||||
|
# --- Tags (workspaces) 1-9 ---
|
||||||
|
++ tagBinds # Generated list of binds for tags 1-9
|
||||||
|
++ [
|
||||||
|
"SUPER,U,viewtoleft_have_client"
|
||||||
|
"SUPER,I,viewtoright_have_client"
|
||||||
|
"SUPER+SHIFT,U,tagtoleft"
|
||||||
|
"SUPER+SHIFT,I,tagtoright"
|
||||||
|
]
|
||||||
|
# --- Close window ---
|
||||||
|
++ [
|
||||||
|
"SUPER,Q,killclient"
|
||||||
|
]
|
||||||
|
# --- Layout / sizing ---
|
||||||
|
++ [
|
||||||
|
"SUPER+SHIFT,R,switch_layout" # Cycle layouts
|
||||||
|
"SUPER,F,spawn_shell,${layoutCmdPath} 'S:${resizePath} fullscreen' 'mmsg dispatch togglemaximizescreen'"
|
||||||
|
"SUPER+SHIFT,F,togglefullscreen"
|
||||||
|
"SUPER,C,centerwin" # Center floating window
|
||||||
|
|
||||||
|
# For Scroller
|
||||||
|
"SUPER,ssharp,spawn_shell,${layoutCmdPath} 'S:${resizePath} down' 'notify-send \"Title\" \"Down\"'"
|
||||||
|
#"SUPER,ssharp,spawn_shell,${resizePath} down"
|
||||||
|
"SUPER,dead_acute,spawn_shell,${layoutCmdPath} 'S:${resizePath} up' 'notify-send \"Title\" \"Up\"'"
|
||||||
|
#"SUPER,dead_acute,spawn_shell,${resizePath} up"
|
||||||
|
]
|
||||||
|
# --- Floating ---
|
||||||
|
++ [
|
||||||
|
"SUPER,V,togglefloating"
|
||||||
|
]
|
||||||
|
# --- Power off monitors ---
|
||||||
|
++ [
|
||||||
|
"SUPER+SHIFT,P,spawn,mmsg dispatch toggle_monitor,eDP-1"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Extra config for settings that don't have structured Nix attrs
|
||||||
|
extraConf = ''
|
||||||
|
# ── Input ──
|
||||||
|
xkb_rules_layout=de
|
||||||
|
numlockon=1
|
||||||
|
mouse_accel_profile=1
|
||||||
|
mouse_accel_speed=-0.4
|
||||||
|
|
||||||
|
# ── Appearance / Theming ──
|
||||||
|
focuscolor=0xffc87faa
|
||||||
|
bordercolor=0x505050ff
|
||||||
|
urgentcolor=0x9b0000ff
|
||||||
|
borderpx=2
|
||||||
|
|
||||||
|
# ── Blur ──
|
||||||
|
blur=1
|
||||||
|
|
||||||
|
blur_params_num_passes=2
|
||||||
|
blur_params_radius=5
|
||||||
|
blur_params_noise=0.02
|
||||||
|
blur_params_brightness=1
|
||||||
|
blur_params_contrast=1
|
||||||
|
blur_params_saturation=1
|
||||||
|
|
||||||
|
# window-rule geometry-corner-radius 12
|
||||||
|
border_radius=12
|
||||||
|
|
||||||
|
# Opacity
|
||||||
|
focused_opacity=1.0
|
||||||
|
unfocused_opacity=0.95
|
||||||
|
|
||||||
|
# ── Layout ──
|
||||||
|
gappih=10
|
||||||
|
gappiv=10
|
||||||
|
gappoh=10
|
||||||
|
gappov=10
|
||||||
|
|
||||||
|
# Master-stack settings (tile layout)
|
||||||
|
default_mfact=0.5
|
||||||
|
default_nmaster=1
|
||||||
|
new_is_master=1
|
||||||
|
|
||||||
|
# Scroller
|
||||||
|
scroller_default_proportion=0.5
|
||||||
|
scroller_focus_center=0
|
||||||
|
scroller_default_proportion_single=1.0
|
||||||
|
|
||||||
|
# Layout cycling order (Mod+R)
|
||||||
|
circle_layout=scroller,tile,center_tile,grid
|
||||||
|
|
||||||
|
# ── Monitor ──
|
||||||
|
monitorrule=name:^eDP-1$,width:2880,height:1920,refresh:120,x:0,y:0,scale:2
|
||||||
|
|
||||||
|
# ── Autostart ──
|
||||||
|
exec-once=noctalia
|
||||||
|
exec-once=lxpolkit
|
||||||
|
exec-once = ${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init
|
||||||
|
|
||||||
|
exec-once="rm -rf ''${XDG_RUNTIME_DIR:-/tmp}/mango-resize"
|
||||||
|
|
||||||
|
tagrule=id:1,layout_name:scroller
|
||||||
|
tagrule=id:2,layout_name:scroller
|
||||||
|
tagrule=id:3,layout_name:scroller
|
||||||
|
tagrule=id:4,layout_name:scroller
|
||||||
|
tagrule=id:5,layout_name:scroller
|
||||||
|
tagrule=id:6,layout_name:scroller
|
||||||
|
tagrule=id:7,layout_name:scroller
|
||||||
|
tagrule=id:8,layout_name:scroller
|
||||||
|
tagrule=id:9,layout_name:scroller
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.mangowm.hmModules.mango
|
||||||
|
../modules/noctalia/home.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
wayland.windowManager.mango = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Additional autostart (most handled in extraConfig exec-once)
|
||||||
|
autostart_sh = "";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
# Key bindings (flat list; keymode for submaps below if needed)
|
||||||
|
bind = defaultBinds;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Raw config lines for options without structured Nix attrs
|
||||||
|
extraConfig = extraConf;
|
||||||
|
};
|
||||||
|
}
|
||||||
21
mango/scripts/layout-cmd.sh
Normal file
21
mango/scripts/layout-cmd.sh
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
tag_json=$(mmsg get all-tags)
|
||||||
|
symbol=$(printf '%s' "$tag_json" | jq -r '
|
||||||
|
.all_tags[0].tags[] | select(.is_active == true) | .layout
|
||||||
|
' | head -1)
|
||||||
|
|
||||||
|
arg1="$1"
|
||||||
|
target_layout="${arg1%%:*}"
|
||||||
|
|
||||||
|
for arg in "${@:1:$#-1}"; do
|
||||||
|
layout="${arg%%:*}"
|
||||||
|
cmd="${arg#*:}"
|
||||||
|
if [ "$symbol" = "$layout" ]; then
|
||||||
|
eval "$cmd"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
eval "${@: -1}"
|
||||||
130
mango/scripts/resize.sh
Normal file
130
mango/scripts/resize.sh
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# 1️⃣ Presets
|
||||||
|
PRESETS=" 0.15 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00"
|
||||||
|
|
||||||
|
# Per-window saved-proportion directory
|
||||||
|
PROPORTION_DIR="${XDG_RUNTIME_DIR:-/tmp}/mango-resize"
|
||||||
|
|
||||||
|
# 2️⃣ Helper: abort with a clear message if a required binary is missing
|
||||||
|
need_cmd() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || {
|
||||||
|
printf "❌ Required command '%s' not found in PATH. Install it first.\n" "$1" >&2
|
||||||
|
exit 127
|
||||||
|
}
|
||||||
|
}
|
||||||
|
need_cmd mmsg
|
||||||
|
need_cmd jq
|
||||||
|
need_cmd awk
|
||||||
|
need_cmd wc
|
||||||
|
need_cmd sed
|
||||||
|
|
||||||
|
# 3️⃣ Get the *currently focused* client.
|
||||||
|
client_json=$(mmsg get focusing-client || true)
|
||||||
|
|
||||||
|
# 3a️⃣ Extract the window's unique id (used as the per-window state key)
|
||||||
|
win_id=$(printf '%s' "$client_json" | jq -r '.id // empty' || true)
|
||||||
|
if [ -z "$win_id" ]; then
|
||||||
|
printf "⚠️ Could not determine window id – aborting.\n" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Per-window state file
|
||||||
|
PROPORTION_FILE="$PROPORTION_DIR/$win_id"
|
||||||
|
|
||||||
|
# 3b️⃣ Extract current client width
|
||||||
|
current=$(printf '%s' "$client_json" | jq -r '.width // empty' || true)
|
||||||
|
|
||||||
|
if [ -z "$current" ]; then
|
||||||
|
printf "⚠️ No focusing client reported – using monitor width as current size.\n"
|
||||||
|
current=$(mmsg get all-monitors | jq -r '
|
||||||
|
if type == "array" then
|
||||||
|
(map(select(.active == true))[0].width)
|
||||||
|
else
|
||||||
|
(.monitors | map(select(.active == true))[0].width)
|
||||||
|
end
|
||||||
|
' || true)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4️⃣ Get the *usable* work‑area width
|
||||||
|
usable_width=$(mmsg get workarea 2>/dev/null || true)
|
||||||
|
if [ -n "$usable_width" ]; then
|
||||||
|
usable_width=$(printf '%s' "$usable_width" | jq -r '.width // empty')
|
||||||
|
fi
|
||||||
|
if [ -z "$usable_width" ]; then
|
||||||
|
usable_width=$(mmsg get all-monitors | jq -r '
|
||||||
|
if type == "array" then
|
||||||
|
(map(select(.active == true))[0].width)
|
||||||
|
else
|
||||||
|
(.monitors | map(select(.active == true))[0].width)
|
||||||
|
end
|
||||||
|
')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5️⃣ Compute the proportion
|
||||||
|
approx=$(awk -v cw="$current" -v uw="$usable_width" '
|
||||||
|
BEGIN {
|
||||||
|
if (uw <= 0) { print "0.50"; exit }
|
||||||
|
printf "%.4f\n", cw / uw
|
||||||
|
}')
|
||||||
|
|
||||||
|
# 6️⃣ Find the nearest preset index
|
||||||
|
nearest_index=$(awk -v target="$approx" '
|
||||||
|
BEGIN {
|
||||||
|
split("'"$PRESETS"'", a, " ");
|
||||||
|
best_i = 1;
|
||||||
|
best_d = 999;
|
||||||
|
for (i = 1; i <= length(a); i++) {
|
||||||
|
d = a[i] - target;
|
||||||
|
if (d < 0) d = -d;
|
||||||
|
if (d < best_d) {
|
||||||
|
best_d = d;
|
||||||
|
best_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print best_i;
|
||||||
|
}')
|
||||||
|
|
||||||
|
# 7️⃣ Apply the direction argument
|
||||||
|
case "${1:-}" in
|
||||||
|
up) new_index=$((nearest_index + 1)) ;;
|
||||||
|
down) new_index=$((nearest_index - 1)) ;;
|
||||||
|
fullscreen)
|
||||||
|
# Check if currently fullscreen (approx >= 0.95 → treat as fullscreen)
|
||||||
|
is_fullscreen=$(awk -v a="$approx" 'BEGIN { print (a >= 0.95) ? "1" : "0" }')
|
||||||
|
if [ "$is_fullscreen" = "1" ]; then
|
||||||
|
# Currently fullscreen → restore this window's saved proportion
|
||||||
|
if [ -f "$PROPORTION_FILE" ]; then
|
||||||
|
saved=$(cat "$PROPORTION_FILE")
|
||||||
|
mmsg dispatch "set_proportion,$saved"
|
||||||
|
printf "✅ [win %s] Restored proportion to %s (fullscreen toggle off)\n" "$win_id" "$saved"
|
||||||
|
rm -f "$PROPORTION_FILE"
|
||||||
|
else
|
||||||
|
printf "⚠️ [win %s] No saved proportion – defaulting to 0.50\n" "$win_id" >&2
|
||||||
|
mmsg dispatch "set_proportion,0.50"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Not fullscreen → save this window's proportion & go fullscreen
|
||||||
|
saved=$(printf '%s\n' $PRESETS | sed -n "${nearest_index}p")
|
||||||
|
mkdir -p "$PROPORTION_DIR"
|
||||||
|
printf '%s' "$saved" > "$PROPORTION_FILE"
|
||||||
|
mmsg dispatch "set_proportion,1.00"
|
||||||
|
printf "✅ [win %s] Saved proportion %s, set to 1.00 (fullscreen toggle on)\n" "$win_id" "$saved"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*) printf "❌ Usage: %s [up|down|fullscreen]\n" "$0" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 8️⃣ Clamp
|
||||||
|
count=$(printf '%s\n' $PRESETS | wc -l)
|
||||||
|
if [ "$new_index" -lt 1 ]; then new_index=1; fi
|
||||||
|
if [ "$new_index" -gt "$count" ]; then new_index=$count; fi
|
||||||
|
|
||||||
|
# 9️⃣ Resolve the new preset value
|
||||||
|
new_value=$(printf '%s\n' $PRESETS | sed -n "${new_index}p")
|
||||||
|
|
||||||
|
# 🔟 Dispatch
|
||||||
|
mmsg dispatch "set_proportion,$new_value"
|
||||||
|
printf "✅ Set proportion to %s (preset %s of %s)\n" "$new_value" "$new_index" "$count"
|
||||||
@ -3,6 +3,7 @@
|
|||||||
./configuration.nix
|
./configuration.nix
|
||||||
|
|
||||||
#./hardware-configuration.nix
|
#./hardware-configuration.nix
|
||||||
|
../mango
|
||||||
../plasma
|
../plasma
|
||||||
../niri
|
../niri
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user