diff --git a/modules/home-manager/desktop/sway/default.nix b/modules/home-manager/desktop/sway/default.nix
index 2b2dc67..b3950e7 100644
--- a/modules/home-manager/desktop/sway/default.nix
+++ b/modules/home-manager/desktop/sway/default.nix
@@ -46,6 +46,24 @@ in
};
};
+ iconTheme = mkOption {
+ type = types.package;
+ default = pkgs.papirus-icon-theme;
+ description = ''Icon theme package to use'';
+ };
+
+ iconThemeName = mkOption {
+ type = types.str;
+ default = "Papirus Dark";
+ description = ''Icon theme variant to use'';
+ };
+
+ iconThemePathname = mkOption {
+ type = types.str;
+ default = "Papirus-Dark";
+ description = ''Icon theme variant to use'';
+ };
+
waybar = {
laptop = mkOption {
type = types.bool;
@@ -107,6 +125,8 @@ in
# emojione
font-awesome
grim
+ hicolor-icon-theme
+ jq
lato
liberation_ttf
libertine
@@ -117,6 +137,7 @@ in
noto-fonts-cjk-sans
slurp
wl-clipboard
+ wl-screenrec
xdg-utils
];
@@ -133,8 +154,8 @@ in
package = pkgs.arc-theme;
};
iconTheme = {
- name = "Papirus Dark";
- package = pkgs.papirus-icon-theme;
+ name = cfg.iconThemeName;
+ package = cfg.iconTheme;
};
font = {
name = "Deja Vu Sans";
diff --git a/modules/home-manager/desktop/sway/includes/files/screencapt.sh b/modules/home-manager/desktop/sway/includes/files/screencapt.sh
new file mode 100755
index 0000000..16b8375
--- /dev/null
+++ b/modules/home-manager/desktop/sway/includes/files/screencapt.sh
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+set -eu -o pipefail
+
+APP_NAME="ScreenCapt"
+
+declare -A COMMAND
+COMMAND=(
+ [screenshot]="grim"
+ [video]="wl-screenrec"
+)
+declare -A ICONS
+ICONS=(
+ ["screenshot"]="accessories-screenshot"
+ ["video"]="record-desktop"
+)
+
+declare -A OUTPUT_DIR
+OUTPUT_DIR=(
+ ["screenshot"]="${XDG_PICTURES_DIR:-"~/pictures"}/screenshots"
+ ["video"]="${XDG_VIDEOS_DIR:="~/videos"}/screenrecords"
+)
+
+declare -A OUTPUT_FILE_EXT
+OUTPUT_FILE_EXT=(
+ ["screenshot"]="png"
+ ["video"]="mp4"
+)
+
+TO_FILE=0
+RECORD_AUDIO=0
+ACTION="screenshot"
+REGION_TYPE="window"
+
+notify() {
+ local summary message command
+ filename="${1:-""}"
+ summary="New ${ACTION}!"
+ if [[ $TO_FILE -eq 1 ]]; then
+ message+="Available in ${filename##*/}"
+ else
+ message+="Available in the clipboard"
+ fi
+ command=(notify-send "${summary}" --app-name="$APP_NAME")
+ if [[ -n "$filename" && "$ACTION" == "screenshots" ]]; then
+ command+=(--icon="${filename}")
+ else
+ command+=("--icon=${ICONS[$ACTION]}")
+ fi
+ command+=("$message")
+ "${command[@]}"
+}
+
+process_args() {
+ while :; do
+ case ''${1:-""} in
+ screenshot)
+ ACTION="$1"
+ ;;
+
+ video)
+ # If a video record is in progress Stop it
+ if pgrep "wl-screenrec"; then
+ kill -s SIGINT $(pgrep "wl-screenrec")
+ exit 0
+ fi
+ TO_FILE=1
+ ACTION="$1"
+ ;;
+ -r | --region)
+ if [[ "${2:-""}" =~ ^(r|region|s|screen|w|window)$ ]]; then
+ REGION_TYPE="$2"
+ else
+ exit 1
+ fi
+ ;;
+ -f | --file)
+ TO_FILE=1
+ ;;
+ -a | --with-audio)
+ RECORD_AUDIO=1
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+get_app_name() {
+ local appname
+ case "$REGION_TYPE" in
+ r | region)
+ appname="region"
+ ;;
+ s | screen)
+ appname="screen"
+ ;;
+ w | window)
+ appname=$(swaymsg -t get_tree | jq -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | "\(.app_id)"')
+ ;;
+ esac
+ printf "%s" "${appname:-}"
+}
+
+get_region() {
+ local region switch
+ case "$REGION_TYPE" in
+ r | region)
+ region=$(slurp)
+ switch="-g"
+ ;;
+ s | screen)
+ region=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | "\(.name)"')
+ switch="-o"
+ ;;
+ w | window)
+ region=$(swaymsg -t get_tree | jq -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | .rect | "\(.x),\(.y) \(.width)x\(.height)"')
+ switch="-g"
+ ;;
+ esac
+ printf "%s%s" "${switch:-}" "${region:-}"
+}
+
+get_output_filename() {
+ local date
+ printf -v date '%(%F_%H.%M.%S)T'
+ printf "%s/%s-%s.%s" "${OUTPUT_DIR[$ACTION]}" "$date" "$(get_app_name)" "${OUTPUT_FILE_EXT[$ACTION]}"
+}
+
+ensure_directories_exist() {
+ for dir in "${!OUTPUT_DIR[@]}"; do
+ mkdir -p "${OUTPUT_DIR[$dir]}"
+ done
+}
+
+main() {
+ process_args "$@"
+ ensure_directories_exist
+ local command
+ command=("${COMMAND[$ACTION]}" "$(get_region)")
+ if [[ "$TO_FILE" -eq 1 ]]; then
+ local filename
+ filename=$(get_output_filename)
+ if [[ "$ACTION" = "video" ]]; then
+ if [[ "$RECORD_AUDIO" -eq 1 ]]; then
+ command+=(--audio)
+ fi
+ command+=(-f)
+ fi
+ command+=("$filename")
+ "${command[@]}"
+ else
+ "${command[@]}" - | wl-copy
+ fi
+ notify "${filename:-""}"
+ exit 0
+}
+
+main "$@"
diff --git a/modules/home-manager/desktop/sway/includes/files/waybar-style.css b/modules/home-manager/desktop/sway/includes/files/waybar-style.css
index ffc4be3..f7cc59f 100644
--- a/modules/home-manager/desktop/sway/includes/files/waybar-style.css
+++ b/modules/home-manager/desktop/sway/includes/files/waybar-style.css
@@ -117,3 +117,17 @@ button:hover{
font-family: "DejaVu sans";
font-size: 12px;
}
+#custom-screenrecord {
+ color: @color-critical;
+ border-bottom: 1px solid @color-critical;
+ animation-name: critical-animation;
+ animation-duration: 2s;
+ animation-timing-function: ease-in-out;
+ animation-direction: alternate;
+ animation-iteration-count: infinite;
+}
+
+@keyframes critical-animation {
+ from {color: @color-critical;}
+ to {color: white;}
+}
diff --git a/modules/home-manager/desktop/sway/includes/mako.nix b/modules/home-manager/desktop/sway/includes/mako.nix
index 3b8d3df..b098010 100644
--- a/modules/home-manager/desktop/sway/includes/mako.nix
+++ b/modules/home-manager/desktop/sway/includes/mako.nix
@@ -1,5 +1,8 @@
{ config, pkgs, lib, ... }:
with lib;
+let
+ cfg = config.modules.desktop.sway;
+in
{
config = mkIf config.modules.desktop.sway.enable {
systemd.user.services.mako = {
@@ -24,12 +27,11 @@ with lib;
border-radius = 0;
border-size = 2;
icons = true;
+ icon-path = "${cfg.iconTheme}/share/icons/${cfg.iconThemePathname}";
max-icon-size = 64;
layer = "overlay";
anchor = "top-right";
- format = ''
- %a\n%s\n%b
- '';
+ format = ''%a\n%s\n%b'';
"urgency=high" = {
border-color = "#F268b3";
};
diff --git a/modules/home-manager/desktop/sway/includes/sway.nix b/modules/home-manager/desktop/sway/includes/sway.nix
index ef2ebbc..4f0874c 100644
--- a/modules/home-manager/desktop/sway/includes/sway.nix
+++ b/modules/home-manager/desktop/sway/includes/sway.nix
@@ -89,9 +89,10 @@ in
"${mod}+a" = "focus parent";
"${mod}+Shift+minus" = "move scratchpad";
"${mod}+minus" = "scratchpad show";
- "${mod}+p" = "exec screenshot window";
- "${mod}+Shift+p" = "exec screenshot screen";
+ "${mod}+p" = "exec screencapt --region window";
+ "${mod}+Shift+p" = "exec screencapt --region screen";
"${mod}+Alt+p" = "mode screenshot";
+ "${mod}+Alt+r" = "mode screenrecord";
# Media stuff
"${mod}+F1" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 1%-";
"${mod}+F2" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s +1%";
@@ -122,12 +123,22 @@ in
"Escape" = "mode default";
};
"screenshot" = {
- "s" = "exec screenshot screen; mode default";
- "Shift+s" = "exec screenshot screen -f; mode default";
- "r" = "exec screenshot region; mode default";
- "Shift+r" = "exec screenshot region -f; mode default";
- "w" = "exec screenshot window; mode default";
- "Shift+w" = "exec screenshot window -f; mode default";
+ "s" = "exec screencapt --region screen; mode default";
+ "Shift+s" = "exec screencapt --region screen -f; mode default";
+ "r" = "exec screencapt --region region; mode default";
+ "Shift+r" = "exec screencapt --region region -f; mode default";
+ "w" = "exec screencapt --region window; mode default";
+ "Shift+w" = "exec screencapt --region window -f; mode default";
+ "Return" = "mode default";
+ "Escape" = "mode default";
+ };
+ "screenrecord" = {
+ "s" = "exec screencapt video --region screen; mode default";
+ "Shift+s" = "exec screencapt --region video screen -a; mde default";
+ "r" = "exec screencapt video --region region; mode default";
+ "Shift+r" = "exec screencapt video --region region -a; mode default";
+ "w" = "exec screencapt video --region window -f ; mode default";
+ "Shift+w" = "exec screencapt --region video window -a; mode default";
"Return" = "mode default";
"Escape" = "mode default";
};
@@ -228,69 +239,9 @@ in
title_align right
'';
};
- home.file.".local/bin/screenshot" = {
+ home.file.".local/bin/screencapt" = {
executable = true;
- text = ''
- #!/usr/bin/env bash
- set -eu -o pipefail
-
- SWAYMSG="${pkgs.sway}/bin/swaymsg"
- JQ="${pkgs.jq}/bin/jq"
- WLCOPY="${pkgs.wl-clipboard}/bin/wl-copy"
- GRIM="${pkgs.grim}/bin/grim"
- SLURP="${pkgs.slurp}/bin/slurp"
-
- # What we want to screenshot
- case ''${1:-} in
- region)
- RECT=$(''$SLURP)
- APPNAME="-region"
- OUTPUT=$(''${SWAYMSG} -t get_outputs | ''${JQ} -r '.[] | select(.focused) | "\(.name)"')
- COMMAND=(
- "''${GRIM}"
- -g
- "''$RECT"
- )
- ;;
- screen)
- OUTPUT=$(''${SWAYMSG} -t get_outputs | ''${JQ} -r '.[] | select(.focused) | "\(.name)"')
- COMMAND=(
- "''${GRIM}"
- -o
- "''${OUTPUT}"
- )
- ;;
- window)
- RECT=$(''${SWAYMSG} -t get_tree | ''${JQ} -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' )
- APPNAME=$(''${SWAYMSG} -t get_tree | ''${JQ} -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | "\(.app_id)"')
- COMMAND=(
- "''${GRIM}"
- -g
- "''${RECT}"
- )
- ;;
- *)
- >&2 printf "Can't understand what you need\n"
- exit 1
- esac
-
- # Where we want to put it
- case ''${2:-"-c"} in
- -c|--clipboard)
- COMMAND+=(-)
- "''${COMMAND[@]}" | ''${WLCOPY}
- ;;
- -f|--file)
- PICTURES_DIR="''${XDG_PICTURES_DIR}/screenshots"
- mkdir -p "''${PICTURES_DIR}"
- printf -v DATE '%(%F_%H.%M.%S)T'
- printf -v FILE "%s/%s-%s%s.png" "''${PICTURES_DIR}" "''${DATE}" "''${OUTPUT:-""}" "''${APPNAME:-""}"
- "''${COMMAND[@]}" "''${FILE//\"/}"
- ;;
- esac
- exit 0
- '';
+ source = ./files/screencapt.sh;
};
-
};
}
diff --git a/modules/home-manager/desktop/sway/includes/waybar.nix b/modules/home-manager/desktop/sway/includes/waybar.nix
index f9c2e6a..85641fa 100644
--- a/modules/home-manager/desktop/sway/includes/waybar.nix
+++ b/modules/home-manager/desktop/sway/includes/waybar.nix
@@ -1,4 +1,4 @@
-{lib, config, ...}:
+{lib, config, pkgs, ...}:
with lib;
let
cfg = config.modules.desktop.sway;
@@ -16,7 +16,9 @@ in
layer = "top";
spacing = 6;
disable-toolptips = true;
- modules-center = [];
+ modules-center = [
+ "custom/screenrecord"
+ ];
modules-left = [
"sway/workspaces"
"sway/mode"
@@ -53,6 +55,7 @@ in
"custom/sep"
"clock"
"custom/sep"
+ "privacy"
"tray"
];
"clock" = {
@@ -73,6 +76,14 @@ in
"format" = "|";
"tooltip" = false;
};
+ "custom/screenrecord" = {
+ "format" = " [rec.] ";
+ "interval" = 1;
+ "exec" = "echo '{\"class\": \"recording\"}'";
+ "exec-if" = "${pkgs.procps}/bin/pgrep wl-screenrec";
+ "on-click" = "exec ${pkgs.coreutils}/bin/kill -s SIGINT $(${pkgs.procps}/bin/pgrep wl-screenrec)";
+ "tooltype" = false;
+ };
"idle_inhibitor" = {
"format" = "{icon}";
"format-icons" = {
@@ -96,6 +107,29 @@ in
"format-wifi" = "{essid} ({signalStrength}%) ";
"tooltip" = false;
};
+ "privacy"= {
+ "icon-spacing" = 4;
+ "icon-size" = 10;
+ "transition-duration" = 250;
+ "modules"= [
+ {
+ "type" = "screenshare";
+ "tooltip" = true;
+ "tooltip-icon-size" = 16;
+ }
+ {
+ "type" = "audio-out";
+ "tooltip" = true;
+ "tooltip-icon-size" = 24;
+ }
+ {
+ "type" = "audio-in";
+ "tooltip" = true;
+ "tooltip-icon-size" = 24;
+ }
+ ];
+ "ignore-monitor" = true;
+ };
"pulseaudio#output" = {
"format" = "{volume}% {icon} ";
"format-bluetooth" = "{volume}% {icon}";