From 42131ebb2cc2b1ed46c555c41d9658997898e927 Mon Sep 17 00:00:00 2001 From: Keyitdev <70140437+Keyitdev@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:56:32 +0200 Subject: [PATCH] Update: Changed screenshot script, added option to exit rofi menu by clicking on background, added new aliases, minor changes in zshrc. etc... --- .../system/getty@tty1.service.d/override.conf | 3 + .../fontconfig/conf.d/99-feather-range.conf | 20 + home/.config/rofi/click-outside.rasi | 26 + home/.config/rofi/dmenu.rasi | 24 +- home/.config/rofi/main.rasi | 28 +- home/.config/rofi/main_without_icons.rasi | 28 +- home/.zshrc | 20 +- usr/local/bin/screenshot | 482 ++++++++++++++---- usr/local/bin/sway-run | 17 + 9 files changed, 497 insertions(+), 151 deletions(-) create mode 100644 etc/systemd/system/getty@tty1.service.d/override.conf create mode 100644 home/.config/fontconfig/conf.d/99-feather-range.conf create mode 100644 home/.config/rofi/click-outside.rasi create mode 100644 usr/local/bin/sway-run diff --git a/etc/systemd/system/getty@tty1.service.d/override.conf b/etc/systemd/system/getty@tty1.service.d/override.conf new file mode 100644 index 0000000..8a9dbf0 --- /dev/null +++ b/etc/systemd/system/getty@tty1.service.d/override.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/usr/bin/agetty --autologin key --noclear %I $TERM diff --git a/home/.config/fontconfig/conf.d/99-feather-range.conf b/home/.config/fontconfig/conf.d/99-feather-range.conf new file mode 100644 index 0000000..6b61884 --- /dev/null +++ b/home/.config/fontconfig/conf.d/99-feather-range.conf @@ -0,0 +1,20 @@ + + + + + + Iosevka Nerd Font + + + + charset + + + 0xe900 + 0xea19 + + + + + + diff --git a/home/.config/rofi/click-outside.rasi b/home/.config/rofi/click-outside.rasi new file mode 100644 index 0000000..19bdf36 --- /dev/null +++ b/home/.config/rofi/click-outside.rasi @@ -0,0 +1,26 @@ +window { + fullscreen: true; + background-color: transparent; + border: 0; + border-radius: 0; + padding: 0; + orientation: vertical; + children: [ button-top, middle, button-bottom ]; +} + +middle { + orientation: horizontal; + expand: false; + background-color: transparent; + children: [ button-left, mainbox, button-right ]; +} + +button-top, button-bottom, button-left, button-right { + expand: true; + background-color: transparent; + action: "kb-cancel"; +} + +mainbox { + expand: false; +} diff --git a/home/.config/rofi/dmenu.rasi b/home/.config/rofi/dmenu.rasi index 207d4ff..0691c9d 100644 --- a/home/.config/rofi/dmenu.rasi +++ b/home/.config/rofi/dmenu.rasi @@ -37,26 +37,32 @@ window { transparency: "real"; - location: north; - anchor: north; - fullscreen: false; - width: 100%; - x-offset: 0px; - y-offset: 0px; - children: [ horibox]; + fullscreen: true; + orientation: vertical; + children: [ horibox, button-bottom]; enabled: true; margin: 0px; padding: 0px; - border: 0px 0px 3px 0px solid; + border: 0px; border-radius: 0px; - border-color: @border-colour; + background-color: transparent; cursor: "default"; } +button-bottom { + expand: true; + padding: 0px; + background-color: transparent; + action: "kb-cancel"; +} + horibox { + expand: false; spacing: 0px; background-color: @background-colour; text-color: @foreground-colour; + border: 0px 0px 3px 0px solid; + border-color: @border-colour; orientation: horizontal; children: [ "prompt", "textbox-prompt-colon", "entry", "listview"]; } diff --git a/home/.config/rofi/main.rasi b/home/.config/rofi/main.rasi index 07c3fd0..13174ea 100644 --- a/home/.config/rofi/main.rasi +++ b/home/.config/rofi/main.rasi @@ -5,7 +5,7 @@ * Copyright (C) 2022-2026 Keyitdev, Aditya Shakya */ -@import "colors.rasi" +@import "colors.rasi" configuration { font: "Roboto mono 14"; @@ -18,20 +18,6 @@ configuration { sidebar-mode: false; } -window { - transparency: "real"; - background-color: @bg; - text-color: @fg; - border: 2px; - border-color: @br; - border-radius: 20px; - // height: 45.3%; - width: 40%; - location: center; - x-offset: 0; - y-offset: 0; -} - prompt { enabled: true; padding: 1.6% 0% 1.5% 1.2%; @@ -74,10 +60,12 @@ listview { } mainbox { - background-color: @al; - border: 0% 0% 0% 0%; - border-radius: 0% 0% 0% 0%; - border-color: @ac; + background-color: @bg; + text-color: @fg; + border: 2px; + border-color: @br; + border-radius: 20px; + width: 40%; children: [ inputbar, listview]; spacing: 0%; padding: 0%; @@ -117,3 +105,5 @@ element selected { border-radius: 0px; border-color: @bg; } + +@import "click-outside.rasi" diff --git a/home/.config/rofi/main_without_icons.rasi b/home/.config/rofi/main_without_icons.rasi index 49553e7..75713db 100644 --- a/home/.config/rofi/main_without_icons.rasi +++ b/home/.config/rofi/main_without_icons.rasi @@ -5,7 +5,7 @@ * Copyright (C) 2022-2026 Keyitdev, Aditya Shakya */ -@import "colors.rasi" +@import "colors.rasi" configuration { font: "Roboto mono 14"; @@ -19,20 +19,6 @@ configuration { } -window { - transparency: "real"; - background-color: @bg; - text-color: @fg; - border: 2px; - border-color: @br; - border-radius: 20px; - //height: 36.54%; - width: 25%; - location: center; - x-offset: 0; - y-offset: 0; -} - prompt { enabled: true; //padding: 1.6% 0% 1.5% 1%; @@ -76,10 +62,12 @@ listview { } mainbox { - background-color: @al; - border: 0% 0% 0% 0%; - border-radius: 0% 0% 0% 0%; - border-color: @ac; + background-color: @bg; + text-color: @fg; + border: 2px; + border-color: @br; + border-radius: 20px; + width: 25%; children: [ inputbar, listview]; spacing: 0%; padding: 0%; @@ -119,3 +107,5 @@ element selected { border-radius: 0px; border-color: @bg; } + +@import "click-outside.rasi" diff --git a/home/.zshrc b/home/.zshrc index daa7765..b5ec16d 100755 --- a/home/.zshrc +++ b/home/.zshrc @@ -36,6 +36,18 @@ precmd() { fi } +vim() { + local f + for f in "$@"; do + [[ $f == -* || $f == +* ]] && continue + if [[ -e $f && ! -w $f ]] || [[ ! -e $f && ! -w ${f:h} ]]; then + sudoedit "$@" + return + fi + done + command vim "$@" +} + # prompt # PROMPT='%F{blue}%B%~%b%f$(git_info) [%*] # %B%(!.#.$)%b ' @@ -107,8 +119,8 @@ alias ......="cd ../../.." alias ........="cd ../../../.." # lazy -alias nemo="nemo ." -alias files="nemo ." +nemo() { command nemo "${@:-.}" &>/dev/null &! } +files() { command nemo "${@:-.}" &>/dev/null &! } alias c="clear" # I know about ctrl l etc. alias g="git" alias py="python3" @@ -120,6 +132,8 @@ alias sudoo="sudo DISPLAY=$DISPLAY WAYLAND_DISPLAY=$WAYLAND_DISPLAY XDG_RUNTIME_ alias help="cat ~/.zshrc | less" alias battery="upower -i $(upower -e | grep BAT)" alias disk_usage="du -sh ./* | sort -hr" +alias disk_usage_btrfs="sudo compsize -x \$(findmnt -l -t btrfs -no TARGET)" +alias disk_usage_btrfs_all="sudo sh -c 'compsize -x \$(findmnt -l -t btrfs -no TARGET) /var/lib/portables /var/lib/machines /.snapshots/*/snapshot'" alias logout="killall -KILL -u $USER" # common mistakes @@ -127,4 +141,4 @@ bindkey "^[[3~" delete-char alias nemo.="nemo ." alias files.="files ." alias code.="code ." -alias kilall="killall" \ No newline at end of file +alias kilall="killall" diff --git a/usr/local/bin/screenshot b/usr/local/bin/screenshot index c3a5bca..e4f5422 100755 --- a/usr/local/bin/screenshot +++ b/usr/local/bin/screenshot @@ -1,5 +1,9 @@ #!/bin/sh +# sudo pacman -S --needed sway grim slurp wf-recorder wl-clipboard jq ffmpeg libnotify libpulse procps-ng python-gobject gtk3 gtk-layer-shell + +[ -z "$WAYLAND_DISPLAY" ] && echo "ERROR: Wayland session required" && exit 1 + # screenshot directory screenshot_directory="$HOME/Pictures/screenshots" videos_directory="$HOME/Videos" @@ -9,131 +13,406 @@ mkdir -p "$screenshot_directory" mkdir -p "$videos_directory" mkdir -p "$audio_directory" -# date=$(date '+%d-%m-%Y-%H-%M-%S_pc') #10-08-2025-18-53-58 filename=$(date '+%Y-%m-%d_%H-%M-%S_pc') #2025-08-10_18-53-58 -# Detect display server -if [ -n "$WAYLAND_DISPLAY" ]; then - DISPLAY_SERVER="wayland"\ - # h264_nvenc libx264rgb - VIDEO_CODEC="libx264rgb" - FRAMERATE=60 - # microphone="$(pactl list sources | grep -A2 'Name:.*input' | grep 'Name:' | head -1 | awk '{print $2}')" - desktop="$(pactl list sources | grep -A2 'Name:.*output' | grep 'Name:' | head -1 | awk '{print $2}')" -else - DISPLAY_SERVER="x11" - # yuv420p yuv444p rgba - VIDEO_CODEC="yuv444p" - FRAMERATE=60 - screen_resolution="$(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/')" -fi +# h264_nvenc libx264rgb +VIDEO_CODEC="libx264rgb" +FRAMERATE=60 +BORDER_WIDTH=2 +BORDER_COLOR="#7F8C8D" -get_area(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - slurp_output="$(slurp)" - x=$(echo "$slurp_output" | cut -d' ' -f1 | cut -d',' -f1) - y=$(echo "$slurp_output" | cut -d' ' -f1 | cut -d',' -f2) - w=$(echo "$slurp_output" | cut -d' ' -f2 | cut -d'x' -f1) - h=$(echo "$slurp_output" | cut -d' ' -f2 | cut -d'x' -f2) - else - slop="$(slop -n -f '%w,%h,%x,%y')" - w=$(echo "$slop" | cut -d ',' -f1) - h=$(echo "$slop" | cut -d ',' -f2) - x=$(echo "$slop" | cut -d ',' -f3) - y=$(echo "$slop" | cut -d ',' -f4) - fi - - [ $((w%2)) -eq 1 ] && w=$(( w + 1 )) - [ $((h%2)) -eq 1 ] && h=$(( h + 1 )) - [ $((x%2)) -eq 1 ] && x=$(( x + 1 )) - [ $((y%2)) -eq 1 ] && y=$(( y + 1 )) - wh="${w}x${h}" - geometry="${x},${y} ${w}x${h}" +desktop="$(pactl get-default-sink).monitor" +output="$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name')" + +window_boxes(){ + swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | "\(.rect.x + .window_rect.x),\(.rect.y + .window_rect.y) \(.window_rect.width)x\(.window_rect.height)"' } -# audio devices (Wayland / PulseAudio) -microphone="$(pactl list short sources | grep input | head -1 | awk '{print $1}')" -desktop="$(pactl list short sources | grep output | head -1 | awk '{print $1}')" +slurp(){ + window_boxes | command slurp -c "#FFFFFFFF" -d "$@" +} + +select_area(){ + python3 - "$BORDER_WIDTH" "$BORDER_COLOR" "$(window_boxes)" << 'EOF' +import subprocess +import sys +import threading +import gi +gi.require_version("Gtk", "3.0") +gi.require_version("GtkLayerShell", "0.1") +gi.require_foreign("cairo") +import cairo +from gi.repository import Gtk, Gdk, GLib, GtkLayerShell + +width = int(sys.argv[1]) +color = Gdk.RGBA() +color.parse(sys.argv[2]) + +boxes = [] +for line in sys.argv[3].splitlines(): + try: + position, size = line.split(" ") + box_x, box_y = map(int, position.split(",")) + box_w, box_h = map(int, size.split("x")) + boxes.append((box_x, box_y, box_w, box_h)) + except ValueError: + pass + +state = {"start": None, "dragged": False, "selection": None, "size": None, "pending": None, "result": None} +condition = threading.Condition() +windows = [] + +def redraw(): + for window in windows: + window.queue_draw() + +def box_at(px, py): + found = [b for b in boxes if b[0] <= px < b[0] + b[2] and b[1] <= py < b[1] + b[3]] + return min(found, key=lambda b: b[2] * b[3]) if found else None + +def set_selection(selection): + if selection == state["selection"]: + return + state["selection"] = selection + state["size"] = None + if selection: + with condition: + state["pending"] = selection + condition.notify() + redraw() + +def apply_size(selection, size): + if selection == state["selection"]: + state["size"] = size + redraw() + return False + +def measure(): + while True: + with condition: + while state["pending"] is None: + condition.wait() + selection = state["pending"] + state["pending"] = None + x, y, w, h = selection + size = 0 + if w > 0 and h > 0: + try: + size = len(subprocess.run(["grim", "-g", f"{x},{y} {w}x{h}", "-"], capture_output=True, check=True).stdout) + except (subprocess.CalledProcessError, OSError): + size = None + GLib.idle_add(apply_size, selection, size) + +def format_size(size): + if size is None: + return "..." + if size >= 1000000000: + decimal = f"{size / 1000000000:.2f} GB" + elif size >= 1000000: + decimal = f"{size / 1000000:.1f} MB" + else: + decimal = f"{size / 1000:.1f} KB" + if size >= 1073741824: + binary = f"{size / 1073741824:.2f} GiB" + elif size >= 1048576: + binary = f"{size / 1048576:.1f} MiB" + else: + binary = f"{size / 1024:.1f} KiB" + return f"{decimal} ({binary})" + +def draw(widget, cr, geometry): + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.set_source_rgba(0, 0, 0, 0) + cr.paint() + cr.set_operator(cairo.OPERATOR_OVER) + + selection = state["selection"] + cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD) + cr.set_source_rgba(0, 0, 0, 0.25) + cr.rectangle(0, 0, geometry.width, geometry.height) + if selection: + cr.rectangle(selection[0] - geometry.x, selection[1] - geometry.y, selection[2], selection[3]) + cr.fill() + + if not selection: + return True + + x, y, w, h = selection + x -= geometry.x + y -= geometry.y + + Gdk.cairo_set_source_rgba(cr, color) + cr.set_line_width(width) + cr.rectangle(x - width / 2, y - width / 2, w + width, h + width) + cr.stroke() + + if not (0 <= x + w - 1 < geometry.width and 0 <= y + h - 1 < geometry.height): + return True + + text = f"{w}x{h} {format_size(state['size'])}" + cr.select_font_face("monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) + cr.set_font_size(14) + ascent, descent = cr.font_extents()[:2] + padding = 6 + box_width = cr.text_extents(text).x_advance + padding * 2 + box_height = ascent + descent + padding * 2 + + box_x = min(max(x + w + width - box_width, 0), geometry.width - box_width) + box_y = y + h + width + 4 + if box_y + box_height > geometry.height: + box_y = max(y - width - 4 - box_height, 0) + + cr.set_source_rgba(0, 0, 0, 0.6) + cr.rectangle(box_x, box_y, box_width, box_height) + cr.fill() + cr.set_source_rgba(1, 1, 1, 1) + cr.move_to(box_x + padding, box_y + padding + ascent) + cr.show_text(text) + return True + +def finish(): + selection = state["selection"] + state["start"] = None + if not selection or selection[2] <= 0 or selection[3] <= 0: + return + state["result"] = selection + Gtk.main_quit() + +def press(widget, event, geometry): + if event.button == 3: + Gtk.main_quit() + return True + if event.button != 1: + return True + state["start"] = (int(event.x) + geometry.x, int(event.y) + geometry.y) + state["dragged"] = False + return True + +def motion(widget, event, geometry): + px = int(event.x) + geometry.x + py = int(event.y) + geometry.y + if state["start"]: + sx, sy = state["start"] + if state["dragged"] or abs(px - sx) > 2 or abs(py - sy) > 2: + state["dragged"] = True + set_selection((min(sx, px), min(sy, py), abs(px - sx), abs(py - sy))) + else: + set_selection(box_at(px, py)) + return True + +def release(widget, event, geometry): + if event.button != 1 or not state["start"]: + return True + if not state["dragged"]: + set_selection(box_at(int(event.x) + geometry.x, int(event.y) + geometry.y)) + finish() + return True + +def key(widget, event): + if event.keyval == Gdk.KEY_Escape: + Gtk.main_quit() + return True + +threading.Thread(target=measure, daemon=True).start() + +display = Gdk.Display.get_default() +for index in range(display.get_n_monitors()): + monitor = display.get_monitor(index) + geometry = monitor.get_geometry() + + window = Gtk.Window() + GtkLayerShell.init_for_window(window) + GtkLayerShell.set_namespace(window, "region-select") + GtkLayerShell.set_layer(window, GtkLayerShell.Layer.OVERLAY) + GtkLayerShell.set_monitor(window, monitor) + GtkLayerShell.set_exclusive_zone(window, -1) + for edge in (GtkLayerShell.Edge.TOP, GtkLayerShell.Edge.BOTTOM, GtkLayerShell.Edge.LEFT, GtkLayerShell.Edge.RIGHT): + GtkLayerShell.set_anchor(window, edge, True) + try: + GtkLayerShell.set_keyboard_mode(window, GtkLayerShell.KeyboardMode.EXCLUSIVE) + except AttributeError: + GtkLayerShell.set_keyboard_interactivity(window, True) + + window.set_app_paintable(True) + window.set_visual(window.get_screen().get_rgba_visual()) + window.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.KEY_PRESS_MASK) + + window.connect("draw", draw, geometry) + window.connect("button-press-event", press, geometry) + window.connect("motion-notify-event", motion, geometry) + window.connect("button-release-event", release, geometry) + window.connect("key-press-event", key) + window.connect("destroy", Gtk.main_quit) + window.show_all() + window.get_window().set_cursor(Gdk.Cursor.new_from_name(display, "crosshair")) + windows.append(window) + +Gtk.main() + +for window in windows: + window.destroy() +display.flush() + +if not state["result"]: + sys.exit(1) + +x, y, w, h = state["result"] +print(f"{x},{y} {w}x{h}") +EOF +} + +show_border(){ + python3 - "$1" "$BORDER_WIDTH" "$BORDER_COLOR" "$2" << 'EOF' & +import os +import sys +import time +import gi +gi.require_version("Gtk", "3.0") +gi.require_version("GtkLayerShell", "0.1") +gi.require_foreign("cairo") +import cairo +from gi.repository import Gtk, Gdk, GLib, GtkLayerShell + +position, size = sys.argv[1].split(" ") +x, y = map(int, position.split(",")) +w, h = map(int, size.split("x")) +width = int(sys.argv[2]) +color = Gdk.RGBA() +color.parse(sys.argv[3]) +path = sys.argv[4] +start = time.monotonic() + +monitor = Gdk.Display.get_default().get_monitor_at_point(x, y) +geometry = monitor.get_geometry() +x -= geometry.x +y -= geometry.y + +window = Gtk.Window() +GtkLayerShell.init_for_window(window) +GtkLayerShell.set_namespace(window, "region-border") +GtkLayerShell.set_layer(window, GtkLayerShell.Layer.OVERLAY) +GtkLayerShell.set_monitor(window, monitor) +GtkLayerShell.set_exclusive_zone(window, -1) +for edge in (GtkLayerShell.Edge.TOP, GtkLayerShell.Edge.BOTTOM, GtkLayerShell.Edge.LEFT, GtkLayerShell.Edge.RIGHT): + GtkLayerShell.set_anchor(window, edge, True) + +window.set_app_paintable(True) +window.set_visual(window.get_screen().get_rgba_visual()) + +def draw(widget, cr): + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.set_source_rgba(0, 0, 0, 0) + cr.paint() + cr.set_operator(cairo.OPERATOR_OVER) + Gdk.cairo_set_source_rgba(cr, color) + cr.set_line_width(width) + cr.rectangle(x - width / 2, y - width / 2, w + width, h + width) + cr.stroke() + + try: + size_bytes = os.path.getsize(path) + except OSError: + size_bytes = 0 + + if size_bytes >= 1000000000: + decimal = f"{size_bytes / 1000000000:.2f} GB" + elif size_bytes >= 1000000: + decimal = f"{size_bytes / 1000000:.1f} MB" + else: + decimal = f"{size_bytes / 1000:.1f} KB" + + if size_bytes >= 1073741824: + binary = f"{size_bytes / 1073741824:.2f} GiB" + elif size_bytes >= 1048576: + binary = f"{size_bytes / 1048576:.1f} MiB" + else: + binary = f"{size_bytes / 1024:.1f} KiB" + + elapsed = int(time.monotonic() - start) + hours, rest = divmod(elapsed, 3600) + minutes, seconds = divmod(rest, 60) + timer = f"{hours}:{minutes:02}:{seconds:02}" if hours else f"{minutes:02}:{seconds:02}" + + text = f"{w}x{h} {decimal} ({binary}) {timer}" + + cr.select_font_face("monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) + cr.set_font_size(14) + ascent, descent = cr.font_extents()[:2] + padding = 6 + box_width = cr.text_extents(text).x_advance + padding * 2 + box_height = ascent + descent + padding * 2 + + box_x = min(max(x + w + width - box_width, 0), geometry.width - box_width) + box_y = y + h + width + 4 + if box_y + box_height > geometry.height: + box_y = max(y - width - 4 - box_height, 0) + + cr.set_source_rgba(0, 0, 0, 0.6) + cr.rectangle(box_x, box_y, box_width, box_height) + cr.fill() + cr.set_source_rgba(1, 1, 1, 1) + cr.move_to(box_x + padding, box_y + padding + ascent) + cr.show_text(text) + return True + +def tick(): + window.queue_draw() + return True + +window.connect("draw", draw) +window.connect("destroy", Gtk.main_quit) +window.show_all() +window.input_shape_combine_region(cairo.Region()) +GLib.timeout_add(500, tick) +Gtk.main() +EOF + border_pid=$! +} screenshot_selected_area(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - geometry="$(slurp)" - grim -g "$geometry" "$screenshot_directory/$filename.png" - wl-copy < "$screenshot_directory/$filename.png" - else - ffcast -q -g "$(slop)" png "$screenshot_directory/$filename.png" - xclip -selection clipboard -t image/png "$screenshot_directory/$filename.png" - fi - notify-send -i "$screenshot_directory/$filename.png" "Screenshot" "Area screenshot taken" + geometry="$(select_area)" || exit 1 + grim -g "$geometry" "$screenshot_directory/$filename.png" + wl-copy < "$screenshot_directory/$filename.png" + notify-send -i "$screenshot_directory/$filename.png" "Screenshot" "Area screenshot taken" } screenshot_full_screen(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - grim "$screenshot_directory/$filename.png" - wl-copy < "$screenshot_directory/$filename.png" - else - ffcast -q png "$screenshot_directory/$filename.png" - xclip -selection clipboard -t image/png "$screenshot_directory/$filename.png" - fi + grim "$screenshot_directory/$filename.png" + wl-copy < "$screenshot_directory/$filename.png" notify-send -i "$screenshot_directory/$filename.png" "Screenshot" "Full screen screenshot taken" } video_selected_area(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - geometry="$(slurp)" - wf-recorder -g "$geometry" -c "$VIDEO_CODEC" -r "$FRAMERATE" -f "$videos_directory/$filename.mp4" - grim -g "$geometry" -t png "/tmp/$filename.png" - else - get_area - ffmpeg -hide_banner -loglevel error -show_region 1 \ - -f x11grab -video_size "$wh" -framerate "$FRAMERATE" -i :0.0+"$x","$y" -pix_fmt "$VIDEO_CODEC" "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" - fi - notify-send -i "/tmp/$filename.png" "Video" "Area video taken" + geometry="$(slurp)" || exit 1 + show_border "$geometry" "$videos_directory/$filename.mp4" + wf-recorder -g "$geometry" -c "$VIDEO_CODEC" -r "$FRAMERATE" -f "$videos_directory/$filename.mp4" + kill "$border_pid" + grim -g "$geometry" -t png "/tmp/$filename.png" + notify-send -i "/tmp/$filename.png" "Video" "Area video taken" } video_full_screen(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - wf-recorder -c "$VIDEO_CODEC" -r "$FRAMERATE" -f "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" 2>/dev/null - else - ffmpeg -hide_banner -loglevel error -show_region 1 \ - -f x11grab -video_size "$screen_resolution" -framerate "$FRAMERATE" -i :0.0 -pix_fmt "$VIDEO_CODEC" "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" - fi - notify-send -i "/tmp/$filename.png" "Video" "Full screen video taken" + wf-recorder -o "$output" -c "$VIDEO_CODEC" -r "$FRAMERATE" -f "$videos_directory/$filename.mp4" + ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" 2>/dev/null + notify-send -i "/tmp/$filename.png" "Video" "Full screen video taken" } video_selected_area_audio(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - geometry="$(slurp)" - wf-recorder -g "$geometry" -c "$VIDEO_CODEC" -r "$FRAMERATE" --audio --audio-device "$desktop" -f "$videos_directory/$filename.mp4" - grim -g "$geometry" -t png "/tmp/$filename.png" - else - get_area - ffmpeg -hide_banner -loglevel error -show_region 1 \ - -f x11grab -video_size "$wh" -framerate "$FRAMERATE" -i :0.0+"$x","$y" \ - -f alsa -i default -pix_fmt "$VIDEO_CODEC" "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" - fi - notify-send -i "/tmp/$filename.png" "Video" "Area video with desktop audio taken" + geometry="$(slurp)" || exit 1 + show_border "$geometry" "$videos_directory/$filename.mp4" + wf-recorder -g "$geometry" -c "$VIDEO_CODEC" -r "$FRAMERATE" --audio="$desktop" -f "$videos_directory/$filename.mp4" + kill "$border_pid" + grim -g "$geometry" -t png "/tmp/$filename.png" + notify-send -i "/tmp/$filename.png" "Video" "Area video with desktop audio taken" } video_full_screen_audio(){ - if [ "$DISPLAY_SERVER" = "wayland" ]; then - wf-recorder -c "$VIDEO_CODEC" -r "$FRAMERATE" --audio --audio-device "$desktop" -f "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" 2>/dev/null - else - ffmpeg -hide_banner -loglevel error -show_region 1 \ - -f x11grab -video_size "$screen_resolution" -framerate "$FRAMERATE" -i :0.0 \ - -f alsa -i default -pix_fmt "$VIDEO_CODEC" "$videos_directory/$filename.mp4" - ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" - fi - notify-send -i "/tmp/$filename.png" "Video" "Full screen video with desktop audio taken" + wf-recorder -o "$output" -c "$VIDEO_CODEC" -r "$FRAMERATE" --audio="$desktop" -f "$videos_directory/$filename.mp4" + ffmpeg -i "$videos_directory/$filename.mp4" -ss 00:00:01.000 -vframes 1 "/tmp/$filename.png" 2>/dev/null + notify-send -i "/tmp/$filename.png" "Video" "Full screen video with desktop audio taken" } stop(){ - pkill -fxn '(/\S+)*ffmpeg\s.*\sx11grab\s.*' pkill -fxn '(/\S+)*ffmpeg\s.*\spulse\s.*' pkill -fxn '(/\S+)*wf-recorder\s.*' pkill -fxn '(/\S+)*pw-record\s.*' @@ -142,7 +421,6 @@ stop(){ help(){ cat << EOF -Display server: $DISPLAY_SERVER -h | -help | --help -s | -stop -sa | -screenshot_selected_area @@ -192,4 +470,6 @@ while [ "$1" != "" ]; do done } -main "$@" \ No newline at end of file +main "$@" + + diff --git a/usr/local/bin/sway-run b/usr/local/bin/sway-run new file mode 100644 index 0000000..75ac8df --- /dev/null +++ b/usr/local/bin/sway-run @@ -0,0 +1,17 @@ +#!/bin/sh + +# Session +export XDG_SESSION_TYPE=wayland +export XDG_SESSION_DESKTOP=sway +export XDG_CURRENT_DESKTOP=sway + +# Wayland stuff +export MOZ_ENABLE_WAYLAND=1 +export QT_QPA_PLATFORM="wayland;xcb" +export SDL_VIDEODRIVER=wayland +export _JAVA_AWT_WM_NONREPARENTING=1 +# GTK theme +export GTK_THEME="gtk-dark-keyitdev:dark" +export GTK_APPLICATION_PREFER_DARK_THEME=1 + +exec sway "$@" --unsupported-gpu