123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- #!/usr/bin/env bash
- # UTILITY FUNCTIONS {{{
- # ===
- _hr="------------"
- # Dump to the screen in a formatted way
- # ---
- #
- # _headline string - First argument, printed above horizontal rule
- # $@ string - Remaining arguments, printed below horizontal rule
- puts() {
- local _headline="$1"
- shift
- local _arr="$@"
- local _i=1
- shift
- printf "\n %s:\n %s\n" "$_headline" "$_hr"
- for _x in ${_arr[@]}; do
- printf " %s. %s\n" "$_i" "$_x"
- (( i++ ))
- done
- unset _headline _i _x _arr
- }
- restart_trayer() {
- starttrayer
- }
- # --------------------------------------------------------------------- }}}
- # XRANDR FUNCTIONS {{{
- # =====
- _local_displays=("LVDS" "eDP1")
- _external_displays=("HDMI" "VGA" "DVI" "DP1")
- # Cache output of xrandr -q
- # ---
- #
- # refresh mixed - whether or not to refresh.
- # Any arugment is true here
- get_xrandr() {
- (( "$#" > 0 )) && xrandr=
- [[ -z "$xrandr" ]] && xrandr=$(xrandr -q)
- }
- get_all() {
- get_xrandr
- xrandr_all=( $(echo "$xrandr" | awk '/connected/ {print $1}' | sort) )
- }
- # Find connected ouputs
- get_connected() {
- get_xrandr
- [[ -z "$xrandr_connected" ]] && \
- xrandr_connected=( $(echo "$xrandr" | awk '/ connected/ {print $1}' | sort) )
- }
- get_disconnected() {
- get_xrandr
- xrandr_disconnected=( $(echo "$xrandr" | awk '/disconnected/ {print $1}' | sort) )
- }
- # Find local, connected output
- get_local() {
- get_connected
- for _local_display in "${_local_displays[@]}"; do
- for _conn_display in "${xrandr_connected[@]}"; do
- if [[ "$_conn_display" == $_local_display* ]]; then
- xrandr_local="$_conn_display"
- break
- fi
- done
- done
- }
- # Find primary external, connected output
- get_external() {
- get_connected
- for _ext_display in "${_external_displays[@]}"; do
- for _conn_display in "${xrandr_connected[@]}"; do
- if [[ "$_conn_display" =~ $_ext_display* ]]; then
- xrandr_external="$_conn_display"
- break
- fi
- done
- done
- }
- mirror() {
- get_local
- get_external
- local _primary="${xrandr_local[0]}"
- local _secondary="${xrandr_external[0]}"
- local -A _native_resolution
- local _auto="--auto"
- # Override navive resolution for high-dpi laptops. Looking at you ASUS Zenbook
- if [[ -r "$HOME/.monitorfix" ]]; then
- _auto=""
- local _override_display=$(grep ^display= "$HOME/.monitorfix" | cut -d= -f2)
- _native_resolution[$_override_display]=$(grep ^native_resolution= "$HOME/.monitorfix" | cut -d= -f2)
- fi
- # require external display
- [[ -z "$xrandr_external" ]] && exit 1
- while read _line; do
- if [[ "$_line" == Screen* ]]; then
- continue
- fi
- if [[ "$_line" == [A-Z]* ]]; then
- set -- $_line
- local _source="$1"
- else
- if [[ -z "${_native_resolution[$_source]}" ]]; then
- set -- $_line
- _native_resolution[$_source]="$(echo "$1" \
- | sed "s/\([[:digit:]]*x[[:digit:]]*\)\?.*/\1/")"
- fi
- fi
- done < <(xrandr -q)
- set -- $(echo ${_native_resolution[$_primary]} | tr "x" " ")
- local _primary_x="$1"
- local _primary_y="$2"
- set -- $(echo ${_native_resolution[$_secondary]} | tr "x" " ")
- local _secondary_x="$1"
- local _secondary_y="$2"
- local _x_scaling=$(echo "scale=4;$_primary_x/$_secondary_x" | bc)
- local _y_scaling=$(echo "scale=4;$_primary_y/$_secondary_y" | bc)
- local _sec="--output $_secondary --scale ${_x_scaling}x${_y_scaling} --auto"
- local _pri="--output $_primary --same-as ${_secondary} --scale 1x1 --primary ${_auto}"
- xrandr $_sec $_pri
- }
- nightmode() {
- get_local
- echo "$1"
- case $1 in
- on|On|ON|oN)
- xrandr --output "$xrandr_local" --gamma 1.68215:1:0.62 --brightness 0.75
- ;;
- of*|oF*|OF*|Of*)
- xrandr --output "$xrandr_local" --gamma 0.97:1:0.98 --brightness 0.98
- ;;
- *)
- show_help
- ;;
- esac
- }
- # Ben Wong, October 1, 2010
- # Public domain. No rights reserved.
- # Functionality extended by Chris Lockfort, August 23, 2012 for use in X230 tablets running gnome-shell.
- tablet() {
- get_local
- rot="$1"
- if [[ -z "$rot" ]]; then
- rot=$(xrandr -q | \
- awk -v display="$xrandr_local" \
- '$0 ~ display {
- gsub("[()]", "")
- gsub("primary ", "")
- print $4
- }')
- echo "The rot is $rot"
- # rot=$(xrandr -q | grep "$xrandr_local" | awk '{print $4}' | tr -d '(')
- fi
- case $rot in
- left) # Currently top is rotated left, we should set it normal (0°)
- xrandr --output "$xrandr_local" --rotate normal
- for _device in $(xsetwacom --list devices | awk '{ print $7 }'); do
- xsetwacom set $_device Rotate none;
- done
- ;;
- normal) # Screen is not rotated, we should rotate it right (90°)
- xrandr --output "$xrandr_local" --rotate right
- for _device in $(xsetwacom --list devices | awk '{ print $7 }'); do
- xsetwacom set $_device Rotate cw;
- done
- ;;
- right) # Top of screen is rotated right, we should invert it (180°)
- xrandr --output "$xrandr_local" --rotate inverted
- for _device in $(xsetwacom --list devices | awk '{ print $7 }'); do
- xsetwacom set $_device Rotate half;
- done
- ;;
- inverted) # Screen is inverted, we should rotate it left (270°)
- xrandr --output "$xrandr_local" --rotate left
- for _device in $(xsetwacom --list devices | awk '{ print $7 }'); do
- xsetwacom set $_device Rotate ccw;
- done
- ;;
- esac
- # restart_trayer
- }
- # --------------------------------------------------------------------- }}}
- # OUTPUT FUNCTIONS {{{
- # ===
- # help function, obvs
- show_help() {
- cat <<HELP
- Usage:
- $0 [COMMAND]...
- COMMANDS:
- all show all connected and disconnected displays
- connected show connected displays
- disconnected show disconnected displays
- local show local connected displays
- external show external connected displays
- mirror mirror local display with first connected display
- nightmode <on|off> modifys the gamma and brightness to approximate xflux
- Example:
- $0 disconnected
- HELP
- }
- show_all() {
- get_all
- puts "All Available Displays" "${xrandr_all[@]}"
- }
- show_connected() {
- get_connected
- puts "Connected Displays" "${xrandr_connected[@]}"
- }
- show_disconnected() {
- get_disconnected
- puts "Connected Displays" "${xrandr_disconnected[@]}"
- }
- show_local() {
- get_local
- puts "Local Connected Display" "${xrandr_local[@]}"
- }
- show_external() {
- get_external
- puts "External Connected Displays" "${xrandr_external[@]}"
- }
- # --------------------------------------------------------------------- }}}
- # MAIN EVENT LOOP {{{
- # ===
- main() {
- local _tabletfile="/tmp/tabletmode"
- case $1 in
- all) show_all ;;
- connected) show_connected ;;
- disconnected) show_disconnected ;;
- local) show_local ;;
- external) show_external ;;
- mirror) mirror ;;
- tablet) tablet ;;
- unfuck)
- notify-send "Attempting to unfuck the display"
- tablet "left" && sleep 2
- tablet "right" && sleep 2
- tablet "left" && sleep 2
- tablet "right" && sleep 2
- tablet "normal"
- ;;
- tabletmode)
- touch $_tabletfile
- if [[ "$(cat $_tabletfile)" == "on" ]]; then
- printf "off" > $_tabletfile
- notify-send "Laptop Mode"
- tablet "left"
- killall cellwriter
- else
- if command -v 'cellwriter' &> /dev/null; then
- cellwriter --window-x=15 --window-y=100 &
- fi
- printf "on" > $_tabletfile
- notify-send "Tablet Mode"
- tablet "right"
- fi
- ;;
- nightmode)
- shift
- nightmode "$1"
- ;;
- *) show_help ;;
- esac
- }
- # --------------------------------------------------------------------- }}}
- main "$@"
|