From 78d3eb21846d0c30d41c141167c7ab39d8ee3191 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 6 Mar 2025 07:35:13 +0100 Subject: [PATCH] Enhance screenshot tools with multi-monitor support and additional capture methods --- README.md | 84 +++++++++++++++++----- i3-config-example.txt | 21 ++++-- i3-screenshot-countdown.sh | 131 ++++++++++++++++++++++++++++++++++ i3-screenshot-import.sh | 0 i3-screenshot-multimonitor.sh | 129 +++++++++++++++++++++++++++++++++ i3-screenshot.sh | 27 ++----- 6 files changed, 345 insertions(+), 47 deletions(-) create mode 100755 i3-screenshot-countdown.sh mode change 100644 => 100755 i3-screenshot-import.sh create mode 100755 i3-screenshot-multimonitor.sh diff --git a/README.md b/README.md index 0dbe287..2edc532 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # i3 Screenshot Tool -A collection of scripts for taking screenshots in i3 window manager on Linux (CachyOS), with a focus on the "freeze and select" functionality. +A collection of scripts for taking screenshots in i3 window manager on Linux (CachyOS), with a focus on the "freeze and select" functionality and multi-monitor support. ## Features +- **Multi-Monitor Support**: Specialized tools for handling multiple displays +- **Monitor Selection**: Choose which monitor to capture (with rofi) +- **Countdown Timer**: Option to use a countdown to avoid capturing menus - **Freeze and Select**: Freeze the screen and then select an area to capture - **Simple Selection**: Direct area selection without freezing (faster but without the freeze effect) +- **Multiple Methods**: Several different approaches to handle compatibility with different systems - **Clipboard Integration**: Automatically copies screenshots to clipboard - **Notifications**: Desktop notifications when screenshots are taken - **Timestamp Naming**: Automatically names files with timestamps @@ -16,12 +20,14 @@ These scripts depend on various Linux utilities. Install them using your package ```bash # For Arch-based distros (including CachyOS) -sudo pacman -S maim slop i3lock feh scrot imagemagick xclip xdotool +sudo pacman -S maim slop feh scrot imagemagick xclip xdotool rofi # For Debian/Ubuntu-based distros -sudo apt install maim slop i3lock feh scrot imagemagick xclip xdotool +sudo apt install maim slop feh scrot imagemagick xclip xdotool rofi ``` +Note: `rofi` is optional but recommended for the multi-monitor script. + ## Installation 1. Clone this repository or download the scripts: @@ -34,7 +40,7 @@ cd i3-screenshot 2. Make the scripts executable: ```bash -chmod +x i3-screenshot.sh i3-screenshot-alt.sh i3-screenshot-simple.sh +chmod +x i3-screenshot*.sh ``` 3. Move the scripts to a directory in your PATH (optional): @@ -48,35 +54,54 @@ sudo cp i3-screenshot*.sh /usr/local/bin/ Add the following lines to your i3 config file (typically `~/.config/i3/config`): ``` -# Screenshot with freeze and area selection (main script) +# Screenshot with area selection (main script, updated for multi-monitor) bindsym Print exec --no-startup-id /path/to/i3-screenshot.sh +# Multi-monitor screenshot with selection menu (requires rofi) +bindsym $mod+Print exec --no-startup-id /path/to/i3-screenshot-multimonitor.sh + +# Countdown screenshot with selection menu (avoids capturing menus) +bindsym $mod+Shift+s exec --no-startup-id /path/to/i3-screenshot-countdown.sh + # Alternative screenshot with freeze and area selection bindsym Shift+Print exec --no-startup-id /path/to/i3-screenshot-alt.sh # Simple screenshot with area selection (no freeze) bindsym Ctrl+Print exec --no-startup-id /path/to/i3-screenshot-simple.sh + +# ImageMagick import-based screenshot +bindsym Mod1+Print exec --no-startup-id /path/to/i3-screenshot-import.sh ``` Replace `/path/to/` with the actual path to the scripts. ## Usage -- Press `Print Screen` to use the main freeze-and-select screenshot tool +- Press `Print Screen` to use the main area selection tool (works with multiple monitors) +- Press `$mod+Print Screen` to use the multi-monitor selection tool with rofi menu +- Press `$mod+Shift+s` to use the countdown screenshot tool (avoids capturing menus) - Press `Shift+Print Screen` to use the alternative freeze-and-select tool - Press `Ctrl+Print Screen` to use the simple area selection tool without freezing +- Press `Alt+Print Screen` to use the ImageMagick import-based tool After pressing the key combination: -1. For the freeze scripts: The screen will freeze, and you can select an area with your mouse -2. For the simple script: The screen will dim, and you can select an area with your mouse -3. The screenshot will be saved to `~/Pictures/Screenshots/` with a timestamp -4. The screenshot will also be copied to your clipboard -5. A notification will appear confirming the screenshot was taken +1. For the multi-monitor script: A menu will appear allowing you to select a specific monitor or area +2. For the countdown script: After selection, a 3-second countdown will start before taking the screenshot +3. For the area selection scripts: The screen will dim, and you can select an area with your mouse +4. The screenshot will be saved to `~/Pictures/Screenshots/` with a timestamp +5. The screenshot will also be copied to your clipboard +6. A notification will appear confirming the screenshot was taken ## How It Works ### Main Script (`i3-screenshot.sh`) -Uses `maim` to take a full screenshot, displays it with `i3lock` to freeze the screen, then uses `slop` for area selection and `maim` again to capture just that area. +Now uses direct area selection with `slop` and `maim` for better multi-monitor support. + +### Multi-Monitor Script (`i3-screenshot-multimonitor.sh`) +Uses `rofi` to provide a selection menu where you can choose to capture a specific monitor, select an area, or take a full screenshot. If `rofi` is not installed, it falls back to area selection mode. Includes a small delay to avoid capturing the menu. + +### Countdown Script (`i3-screenshot-countdown.sh`) +Similar to the multi-monitor script, but adds a 3-second countdown before taking the screenshot. This ensures that any menus (like the rofi selection menu) are completely gone before the screenshot is taken. ### Alternative Script (`i3-screenshot-alt.sh`) Uses `scrot` for the initial screenshot, `feh` to display it fullscreen, `slop` for selection, and `imagemagick` to crop the image. @@ -84,19 +109,40 @@ Uses `scrot` for the initial screenshot, `feh` to display it fullscreen, `slop` ### Simple Script (`i3-screenshot-simple.sh`) Uses just `maim` with the `-s` flag for direct area selection without freezing the screen first. +### Import Script (`i3-screenshot-import.sh`) +Uses ImageMagick's `import` command, which provides its own selection interface. This may work better on some systems where the other methods fail. + +## Multi-Monitor Troubleshooting + +- **Screenshots span across multiple monitors**: Use the `i3-screenshot-multimonitor.sh` script to select a specific monitor +- **Selection tool appears on the wrong monitor**: Try using the `i3-screenshot-import.sh` script instead +- **Rofi menu doesn't appear**: Make sure `rofi` is installed (`sudo pacman -S rofi`) +- **Rofi menu appears in the screenshot**: Use the `i3-screenshot-countdown.sh` script which waits before taking the screenshot + +## General Troubleshooting + +### Common Issues + +- **Screen freezes but selection doesn't work**: The main script has been updated to use direct selection without freezing +- **Selection tool doesn't appear**: Make sure `slop` is installed and working correctly +- **Black screenshots**: This can happen with compositing issues. Try using the `i3-screenshot-import.sh` script instead +- **Menu appears in screenshots**: Use the countdown script which gives time for menus to disappear + +### General Tips + +- If the scripts don't work, make sure all dependencies are installed +- Check that the scripts have executable permissions +- Verify your i3 config has the correct paths to the scripts +- Try each of the different scripts to see which works best on your system + ## Customization You can modify the scripts to change: - The save location by editing the `SAVE_DIR` variable - The notification messages - The file naming convention - -## Troubleshooting - -- If the scripts don't work, make sure all dependencies are installed -- Check that the scripts have executable permissions -- Verify your i3 config has the correct paths to the scripts -- If using the i3lock method, ensure your system supports i3lock with image display +- The rofi appearance and options in the multi-monitor script +- The countdown duration in the countdown script ## License diff --git a/i3-config-example.txt b/i3-config-example.txt index 113cbe6..928272f 100644 --- a/i3-config-example.txt +++ b/i3-config-example.txt @@ -1,18 +1,27 @@ # i3 config file example for screenshot tool bindings # Add these lines to your i3 config file (typically ~/.config/i3/config) -# Screenshot with freeze and area selection (main script) +# Screenshot with area selection (main script, updated for multi-monitor) bindsym Print exec --no-startup-id /path/to/i3-screenshot.sh +# Multi-monitor screenshot with selection menu (requires rofi) +bindsym $mod+Print exec --no-startup-id /path/to/i3-screenshot-multimonitor.sh + +# Countdown screenshot with selection menu (avoids capturing menus) +bindsym $mod+Shift+s exec --no-startup-id /path/to/i3-screenshot-countdown.sh + # Alternative screenshot with freeze and area selection bindsym Shift+Print exec --no-startup-id /path/to/i3-screenshot-alt.sh # Simple screenshot with area selection (no freeze) bindsym Ctrl+Print exec --no-startup-id /path/to/i3-screenshot-simple.sh -# You can also add more specific bindings if needed -# For example, to capture the active window: -bindsym $mod+Print exec --no-startup-id maim -i $(xdotool getactivewindow) | xclip -selection clipboard -t image/png +# ImageMagick import-based screenshot +bindsym Mod1+Print exec --no-startup-id /path/to/i3-screenshot-import.sh -# Or to capture the entire screen: -bindsym $mod+Shift+Print exec --no-startup-id maim | xclip -selection clipboard -t image/png \ No newline at end of file +# Additional bindings for specific use cases +# Capture the active window: +bindsym $mod+Shift+Print exec --no-startup-id maim -i $(xdotool getactivewindow) | xclip -selection clipboard -t image/png + +# Capture the entire screen: +bindsym $mod+Ctrl+Print exec --no-startup-id maim | xclip -selection clipboard -t image/png \ No newline at end of file diff --git a/i3-screenshot-countdown.sh b/i3-screenshot-countdown.sh new file mode 100755 index 0000000..9064394 --- /dev/null +++ b/i3-screenshot-countdown.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +# i3-screenshot-countdown.sh - Tool for taking screenshots with a countdown +# This script provides a countdown before taking the screenshot to avoid capturing menus + +# Default save location - user's Pictures directory +SAVE_DIR="$HOME/Pictures/Screenshots" +TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) +SCREENSHOT_PATH="$SAVE_DIR/screenshot_$TIMESTAMP.png" + +# Create the save directory if it doesn't exist +mkdir -p "$SAVE_DIR" + +# Function to display notification +notify() { + notify-send "Screenshot Tool" "$1" -i camera-photo +} + +# Function to get a list of monitors +get_monitors() { + xrandr --listactivemonitors | grep -v "Monitors" | awk '{print $4}' +} + +# Function to get monitor geometry +get_monitor_geometry() { + local monitor=$1 + xrandr | grep "$monitor" | grep -oP '\d+x\d+\+\d+\+\d+' +} + +# Function to do a countdown before taking the screenshot +countdown_screenshot() { + # Countdown from 3 + for i in 3 2 1; do + notify "Taking screenshot in $i..." + sleep 1 + done + + # Take the screenshot + if [ -n "$1" ]; then + maim -g "$1" "$SCREENSHOT_PATH" + else + maim "$SCREENSHOT_PATH" + fi + + # Check if screenshot was successful + if [ $? -ne 0 ]; then + notify "Screenshot failed" + exit 1 + fi +} + +# Check if rofi is installed +if ! command -v rofi &> /dev/null; then + notify "Rofi is not installed. Using direct selection mode." + + # Use slop to select an area and maim to take the screenshot + notify "Select an area to capture" + SELECTION=$(slop -f "%x,%y,%w,%h") + if [ $? -ne 0 ]; then + notify "Screenshot canceled" + exit 1 + fi + + # Extract coordinates and dimensions + IFS=',' read -r X Y W H <<< "$SELECTION" + + # Take the screenshot of the selected area with countdown + countdown_screenshot "${W}x${H}+${X}+${Y}" +else + # Get list of monitors + MONITORS=$(get_monitors) + + # Add "Select Area" and "Full Screenshot" options + OPTIONS="Select Area\nFull Screenshot" + + # Add each monitor to the options + for MONITOR in $MONITORS; do + OPTIONS="$OPTIONS\n$MONITOR" + done + + # Show selection menu with rofi + CHOICE=$(echo -e "$OPTIONS" | rofi -dmenu -i -p "Screenshot Mode") + + case "$CHOICE" in + "Select Area") + # Use slop to select an area + notify "Select an area to capture" + SELECTION=$(slop -f "%x,%y,%w,%h") + if [ $? -ne 0 ]; then + notify "Screenshot canceled" + exit 1 + fi + + # Extract coordinates and dimensions + IFS=',' read -r X Y W H <<< "$SELECTION" + + # Take the screenshot of the selected area with countdown + countdown_screenshot "${W}x${H}+${X}+${Y}" + ;; + + "Full Screenshot") + # Take screenshot of all monitors with countdown + countdown_screenshot + ;; + + *) + # Take screenshot of selected monitor + if [ -n "$CHOICE" ]; then + GEOMETRY=$(get_monitor_geometry "$CHOICE") + if [ -n "$GEOMETRY" ]; then + notify "Taking screenshot of monitor $CHOICE..." + countdown_screenshot "$GEOMETRY" + else + notify "Could not determine monitor geometry" + exit 1 + fi + else + notify "Screenshot canceled" + exit 1 + fi + ;; + esac +fi + +# Copy to clipboard +xclip -selection clipboard -t image/png -i "$SCREENSHOT_PATH" + +# Notify user +notify "Screenshot saved to $SCREENSHOT_PATH and copied to clipboard" + +echo "Screenshot saved to: $SCREENSHOT_PATH" \ No newline at end of file diff --git a/i3-screenshot-import.sh b/i3-screenshot-import.sh old mode 100644 new mode 100755 diff --git a/i3-screenshot-multimonitor.sh b/i3-screenshot-multimonitor.sh new file mode 100755 index 0000000..043cce9 --- /dev/null +++ b/i3-screenshot-multimonitor.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +# i3-screenshot-multimonitor.sh - Tool for taking screenshots with multi-monitor support +# This script provides options for selecting a specific monitor or area + +# Default save location - user's Pictures directory +SAVE_DIR="$HOME/Pictures/Screenshots" +TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) +SCREENSHOT_PATH="$SAVE_DIR/screenshot_$TIMESTAMP.png" + +# Create the save directory if it doesn't exist +mkdir -p "$SAVE_DIR" + +# Function to display notification +notify() { + notify-send "Screenshot Tool" "$1" -i camera-photo +} + +# Function to get a list of monitors +get_monitors() { + xrandr --listactivemonitors | grep -v "Monitors" | awk '{print $4}' +} + +# Function to get monitor geometry +get_monitor_geometry() { + local monitor=$1 + xrandr | grep "$monitor" | grep -oP '\d+x\d+\+\d+\+\d+' +} + +# Function to take a screenshot with a delay +take_delayed_screenshot() { + # Add a small delay to ensure any menus are closed + sleep 0.5 + + # Take the screenshot + if [ -n "$1" ]; then + maim -g "$1" "$SCREENSHOT_PATH" + else + maim "$SCREENSHOT_PATH" + fi + + # Check if screenshot was successful + if [ $? -ne 0 ]; then + notify "Screenshot failed" + exit 1 + fi +} + +# Check if rofi is installed +if ! command -v rofi &> /dev/null; then + notify "Rofi is not installed. Using direct selection mode." + + # Use slop to select an area and maim to take the screenshot + notify "Select an area to capture" + SELECTION=$(slop -f "%x,%y,%w,%h") + if [ $? -ne 0 ]; then + notify "Screenshot canceled" + exit 1 + fi + + # Extract coordinates and dimensions + IFS=',' read -r X Y W H <<< "$SELECTION" + + # Take the screenshot of the selected area + take_delayed_screenshot "${W}x${H}+${X}+${Y}" +else + # Get list of monitors + MONITORS=$(get_monitors) + + # Add "Select Area" and "Full Screenshot" options + OPTIONS="Select Area\nFull Screenshot" + + # Add each monitor to the options + for MONITOR in $MONITORS; do + OPTIONS="$OPTIONS\n$MONITOR" + done + + # Show selection menu with rofi + CHOICE=$(echo -e "$OPTIONS" | rofi -dmenu -i -p "Screenshot Mode") + + case "$CHOICE" in + "Select Area") + # Use slop to select an area + notify "Select an area to capture" + SELECTION=$(slop -f "%x,%y,%w,%h") + if [ $? -ne 0 ]; then + notify "Screenshot canceled" + exit 1 + fi + + # Extract coordinates and dimensions + IFS=',' read -r X Y W H <<< "$SELECTION" + + # Take the screenshot of the selected area + take_delayed_screenshot "${W}x${H}+${X}+${Y}" + ;; + + "Full Screenshot") + # Take screenshot of all monitors + notify "Taking full screenshot..." + take_delayed_screenshot + ;; + + *) + # Take screenshot of selected monitor + if [ -n "$CHOICE" ]; then + GEOMETRY=$(get_monitor_geometry "$CHOICE") + if [ -n "$GEOMETRY" ]; then + notify "Taking screenshot of monitor $CHOICE..." + take_delayed_screenshot "$GEOMETRY" + else + notify "Could not determine monitor geometry" + exit 1 + fi + else + notify "Screenshot canceled" + exit 1 + fi + ;; + esac +fi + +# Copy to clipboard +xclip -selection clipboard -t image/png -i "$SCREENSHOT_PATH" + +# Notify user +notify "Screenshot saved to $SCREENSHOT_PATH and copied to clipboard" + +echo "Screenshot saved to: $SCREENSHOT_PATH" \ No newline at end of file diff --git a/i3-screenshot.sh b/i3-screenshot.sh index 35310a4..08e4aab 100755 --- a/i3-screenshot.sh +++ b/i3-screenshot.sh @@ -1,7 +1,7 @@ #!/bin/bash # i3-screenshot.sh - A tool for taking selective screenshots in i3 window manager -# This script freezes the screen and allows selecting an area for screenshot +# This script allows selecting an area for screenshot with multi-monitor support # Default save location - user's Pictures directory SAVE_DIR="$HOME/Pictures/Screenshots" @@ -16,39 +16,22 @@ notify() { notify-send "Screenshot Tool" "$1" -i camera-photo } -# Take a full screenshot first to use as the frozen background -TEMP_SCREENSHOT="/tmp/frozen_screen_$TIMESTAMP.png" -maim "$TEMP_SCREENSHOT" - -# Display the frozen screenshot as a background using feh instead of i3lock -feh --fullscreen --borderless "$TEMP_SCREENSHOT" & -FEH_PID=$! - -# Wait a moment for feh to display the image -sleep 0.5 - -# Use slop to select an area and maim to take the screenshot +# Use slop to select an area and maim to take the screenshot directly +# This works better with multiple monitors +notify "Select an area to capture" SELECTION=$(slop -f "%x,%y,%w,%h") if [ $? -ne 0 ]; then # User canceled the selection - kill $FEH_PID - rm "$TEMP_SCREENSHOT" notify "Screenshot canceled" exit 1 fi -# Kill the feh process -kill $FEH_PID - # Extract coordinates and dimensions IFS=',' read -r X Y W H <<< "$SELECTION" -# Take the actual screenshot of the selected area +# Take the screenshot of the selected area maim -g "${W}x${H}+${X}+${Y}" "$SCREENSHOT_PATH" -# Clean up -rm "$TEMP_SCREENSHOT" - # Copy to clipboard xclip -selection clipboard -t image/png -i "$SCREENSHOT_PATH"