#!/bin/bash # Resize new Firefox windows - For https://stackoverflow.com/q/66297454/1765658 # (C) 2023 - F-Hauri.ch # Licensed by GNU GENERAL PUBLIC LICENSE Version 3 # Require: xdotool wmctrl and firefox defaultUrl="https://stackoverflow.com/search?tab=votes&q=user%3A1765658+firefox" defaultGeom=1200x900+200+120 usage() { dspchoice=("${!displays[@]}") printf -v dspchoice[0] '\47%s\47, ' "${dspchoice[@]:0:${#dspchoice[@]}-1}" cat <<-EOUsage Usage: ${0##*/} [-h] [ -g str | [ [ -p int | [-x int] [-y int] ] [-d str] [URL] -d str Display either ${dspchoice[0]%, } or '${dspchoice[@]: -1}'. -g str Geometry string in format 'WxH+X+Y' (must be alone). -h Show this. -p int Percent of display. -x int Percent width of display. -y int Percent height of display. URL Default to '$defaultUrl'. EOUsage } die() { echo >&2 "${0##*/} ERR: $*"; exit 1;} mkBound() { local refstr=({0..9} _ {A..Z} '=' {a..z}) tfmt sfmt printf -v sfmt %8s '' tfmt=("${sfmt// /%s}"{,,}{,}) sfmt=${tfmt[*]} sfmt=${tfmt// /-} # shellcheck disable=SC2059 printf -v bound "$sfmt" "${refstr[RANDOM%64]}"{,,}{,,,}{,,,} } getDispSize() { if [[ -v display ]];then [[ -v "displays[$display]" ]] || die "Can't found display '$display'." geometry=${displays[$display]} else if [[ -v displays[secondary] ]];then ar=('' "${displays[root]}") printf '%3d: %s (%s)\n' 1 Root whole\ display while IFS=' x+' read -r dev stat a b c d e _; do if [[ $stat == connected ]]; then typ=secondary [[ $a == primary ]] && typ=${a} a=$b b=$c c=$d d=$e printf '%3d: %s (%s)\n' ${#ar[@]} "$dev" "$typ" ar+=("${a}x$b+$c+$d") fi done < <(LANG=C exec xrandr) read -p 'Wich display: ' -rsn 1 userKey if [[ ${ar[userKey]} ]]; then geometry=${ar[userKey]} echo "$userKey" else echo user abort exit 1 fi else geometry="${displays[root]}" fi fi } splitGeom() { width=${geometry%%x*} height=${geometry#${width}x} height=${height%%[+-]*} xpos=${geometry#${width}x$height} [[ ${xpos%[+-]*} ]] && xpos=${xpos%[+-]*} ypos=${geometry#${width}x$height$xpos} [[ $xpos ]] || xpos=+0 [[ $ypos ]] || ypos=+0 } scaleGeom() { local _xpct=$1 _ypct=$2 getDispSize splitGeom geometry=$(( width * _xpct / 100 ))x$(( height * _ypct / 100 ))+$(( xpos + ( width - width * _xpct / 100 ) / 2 ))+$(( ypos + ( height- height* _ypct / 100 ) / 2 )) } declare -A displays=() while IFS=' x+' read -r cmd a ;do [[ $cmd == -geometry ]] && displays[root]=$a done < <(LANG=C exec xwininfo -root) while read -r dev state typ geom _; do if [[ $state == connected ]];then if [[ $typ == primary ]];then displays[primary]="$geom" else geom="$typ" displays[secondary]="$geom" fi displays[$dev]="$geom" fi done < <(LANG=C exec xrandr) while getopts "hd:g:p:x:y:" opt;do case $opt in h ) usage; exit 0 ;; d ) [[ -v displays[$OPTARG] ]] || die "There is no '$OPTARG' display." display=$OPTARG ;; g ) geometry=$OPTARG ;; p ) prct=$OPTARG ;; x ) xpct=$OPTARG ;; y ) ypct=$OPTARG ;; ? ) b=$((OPTIND-1)); die "'${!b}' not valid option." ;; * ) usage; die "opt: '$opt' ??" ;; esac done shift $((OPTIND-1)) targetUrl="${1:-$defaultUrl}" if [[ -v geometry ]] ;then { [[ -v prct ]] || [[ -v ypct ]] || [[ -v xpct ]] ;} && die "-g parm can't be used with any of -p -x or -y." elif [[ -v prct ]] ;then { [[ -v ypct ]] || [[ -v xpct ]] ;} && die "-p parm can't be used with any of -x or -y." scaleGeom "$prct" "$prct" elif [[ -v xpct ]] ;then scaleGeom "$xpct" "${ypct:-100}" elif [[ -v ypct ]] ;then scaleGeom 100 "$ypct" else geometry="$defaultGeom" fi splitGeom mkBound printf -v ffurl "data:text/html;ascii,<head><title>%s</title></head>" "$bound" firefox --new-window "$ffurl" while ffwin=$(wmctrl -l|sed -ne "/$bound/s/ .*$//gp");[[ -z ${ffwin} ]] ;do echo -n . sleep .05 done echo xdotool windowraise "$ffwin" xdotool windowfocus "$ffwin" xdotool windowactivate "$ffwin" xdotool windowsize "$ffwin" "$width" "$height" xdotool windowmove "$ffwin" "$xpos" "$ypos" xdotool windowsize "$ffwin" "$width" "$height" xdotool windowmove "$ffwin" "$xpos" "$ypos" xdotool windowactivate "$ffwin" xdotool key ctrl+l sleep .8 xdotool type --delay 22 "$targetUrl" xdotool key Return