From b66e7e661bbf7471e0d208b3c3953562fad57f4b Mon Sep 17 00:00:00 2001 From: noctuid Date: Fri, 1 Jul 2016 17:26:45 -0400 Subject: [PATCH] Allow -x and -y to take a percentage or negative With this, '-m' is no longer required for negative values to be used with any of the geometry options (-w/-y/-x/-y). Also, tdrop no longer relies on xdotool's ability to take percentages directly (for windowsize). Fixes #19. --- README.md | 6 ++--- tdrop | 70 +++++++++++++++++++++++++++++++++++------------------ tdrop.groff | 8 +++--- 3 files changed, 54 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index fddbcca..ac08e4c 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,9 @@ s. It is usually worse on tiling managers where the window must be re-floated ev However, the consistent way to eliminate visual flickering due to moving/resizing for any window manager is to enable fade-in for the compositor. For compton this can be done by setting `fading = true;` and adjusting the `fade-delta` in the .compton.conf accordingly. ### Monitor Awareness -Using the `-m`/`--monitor-aware` flag has two purposes. For those who use a single monitor, it allows specifying a negative number to `-w` or `-h`. For example, `-w -4` corresponds to a width 4 pixels less than 100% of the screen width. This may be useful when the window manager (possibly due to window decorations) causes a dropdown with `-w 100%` to go over the edge of the screen. +Using the `-m`/`--monitor-aware` flag will cause the geometry options to act with respect to the current monitor. This may be helpful for users of multiple monitors who don't want dropdowns spanning across monitors. -For those who use multiple monitors, using `-m` will additionally alter the width and height options to correspond to the current monitor. This means that `-w 100%` will cause the dropdown to occupy the full width of the current monitor instead of spanning all monitors. Also, the `-m` option will automatically resize the dropdown when opening it on a different monitor if the width or height arguments are negative or percentages. +This is particularly useful when using a percentage or negative value with `-w`, `-h`, `-x`, and/or `-y`. For example, `-w -4` normally corresponds to a width 4 pixels less than 100% of the screen width (potentially the combined width of multiple monitors). With `-m`, the pixel values are calculated using the dimensions of the current monitor alone. Negative values may be useful when the window manager (possibly due to window decorations) causes a dropdown with `-w 100%` to go over the edge of the screen. The `-m` option will also automatically resize and/or reposition the dropdown when opening it on a different monitor when one or more of the geometry arguments are negative or percentages. Some window managers allow querying what the current monitor is (e.g. bspwm and i3), but for other window managers, tdrop determines the current monitor based on the position of the active window. For these window managers, if the desktop is empty, tdrop must wait for the dropdown to be created or mapped before getting the monitor info. This may cause a slight delay before the dropdown is properly resized. If `-m` does not work at all or there is a specific way to query for the current monitor in your window manager, please make an issue. @@ -135,7 +135,7 @@ Awesome support may be buggy; if you encounter problems, please report them. Unm Necessary features don't work on many window managers, including mine. ## Why Not Use wmutils? -Maybe in the future. The only advantage I can see over xdotool is that it can toggle mapping (`mapw -t`), but this wouldn't be used in this script anyway since different code is executed depending on whether or not the window is mapped or unmapped. Also the command names are somewhat cryptic and resizing to a percentage isn't supported (would have to convert percentages to pixels). +Maybe in the future. The only advantage I can see over xdotool is that it can toggle mapping (`mapw -t`), but this wouldn't be used in this script anyway since different code is executed depending on whether or not the window is mapped or unmapped. Also the command names are somewhat cryptic. ## Similar: - [drawer](https://github.com/lharding/lsh-bin/blob/master/drawer) diff --git a/tdrop b/tdrop index 9c5bc33..ad0af37 100755 --- a/tdrop +++ b/tdrop @@ -129,13 +129,6 @@ if [[ $# -ne 1 ]]; then exit 1 fi -# require -m for negative width or height -if ! $monitor_aware && [[ $height$width == *-* ]]; then - echo >&2 "-m is required to use negative width or height values." | \ - tee -a /tmp/tdrop/log - exit 1 -fi - # validate options that require number values if [[ ! $height$width$xoff$yoff =~ ^[0-9%-]*$ ]]; then echo >&2 "The -h, -w, -x, and -y values must be numbers (or percentages)." | \ @@ -173,6 +166,41 @@ focused_window_exists=true # Multiple Monitor Automatic Re-Sizing # +percent_of_total() { # percent total + awk "BEGIN {printf(\"%.0f\", 0.01*${1%\%}*$2)}" +} + +# acts on globals +convert_geometry_to_pixels() { + total_width=$1 + total_height=$2 + local minus_width minus_height minus_xoff minus_yoff + if [[ $width =~ %$ ]]; then + width=$(percent_of_total "$width" "$total_width") + elif [[ $width =~ ^- ]]; then + minus_width=${width#-} + width=$((total_width-minus_width)) + fi + if [[ $height =~ %$ ]]; then + height=$(percent_of_total "$height" "$total_height") + elif [[ $height =~ ^- ]]; then + minus_height=${height#-} + height=$((total_height-minus_height)) + fi + if [[ $xoff =~ %$ ]]; then + xoff=$(percent_of_total "$xoff" "$total_width") + elif [[ $xoff =~ ^- ]]; then + minus_xoff=${xoff#-} + xoff=$((total_width-minus_xoff)) + fi + if [[ $yoff =~ %$ ]]; then + yoff=$(percent_of_total "$yoff" "$total_height") + elif [[ $yoff =~ ^- ]]; then + minus_yoff=${yoff#-} + yoff=$((total_height-minus_yoff)) + fi +} + update_geometry_settings_for_monitor() { # 1. Correctly interpret width/height percentages when there exist multiple # monitors so an initially created dropdown is the correct size (xdotool @@ -182,8 +210,7 @@ update_geometry_settings_for_monitor() { # was used # it is conceivable that a user may want to use -m but not -a, so - # get the wm from with - # in this function + # get the wm from within this function local wm current_monitor wm=$(get_window_manager) if [[ $wm == bspwm ]]; then @@ -235,25 +262,14 @@ update_geometry_settings_for_monitor() { done <<< "$monitors_info" fi + # convert w/h/x/y percentages/negatives to pixels + convert_geometry_to_pixels "$x_width" "$y_height" + # update x and y offsets, so that will appear on correct screen # (required for some WMs apparently, but not for others) ((xoff+=x_begin)) ((yoff+=y_begin)) - # convert w/h percentages to pixels based on size of current screen - if [[ $height =~ %$ ]]; then - height=$(awk "BEGIN {printf(\"%.0f\", 0.01*${height%\%}*$y_height)}") - elif [[ $height =~ ^- ]]; then - minus_height=${height#-} - height=$((y_height-minus_height)) - fi - if [[ $width =~ %$ ]]; then - width=$(awk "BEGIN {printf(\"%.0f\", 0.01*${width%\%}*$x_width)}") - elif [[ $width =~ ^- ]]; then - minus_width=${width#-} - width=$((x_width-minus_width)) - fi - # determine if monitor has changed and save current monitor local last_monitor last_monitor=$(< /tmp/tdrop/last_monitor) 2> /dev/null @@ -550,6 +566,14 @@ current_create() { } wid_toggle() { + # deal with percentages/negatives when no -m + if ! $monitor_aware; then + local total_geo total_width total_height + total_geo=$(xwininfo -root | awk '/geometry/ {print $2}') + total_width=$(echo "$total_geo" | awk -F 'x' '{print $1}') + total_height=$(echo "$total_geo" | awk -F 'x|+' '{print $2}') + convert_geometry_to_pixels "$total_width" "$total_height" + fi # get saved window id if already created local wid exists visibility wid=$(< /tmp/tdrop/"$program$num") 2> /dev/null diff --git a/tdrop.groff b/tdrop.groff index ab82b23..0d6d4ab 100644 --- a/tdrop.groff +++ b/tdrop.groff @@ -18,12 +18,12 @@ E.g. .br $ tdrop --y-offset=15 termite .TP +\fB\-w\fR, \fB \-\-width\fR +Specify a width for a created window as a number or percentage. A negative number is allowed (e.g. '-w -4') in which case the width will be that many pixels less than 100% of the screen size (or monitor size if '-m' is being used). This fixes the problem where 100% width may actually go over the screen due to window borders/decoration. The other other geometry options also accept negative values ('-h', '-x', and '-y'). (default: 100%) +.TP \fB\-h\fR, \fB \-\-height\fR Specify a height for a created window as a number or percentage. (default: 45%) .TP -\fB\-w\fR, \fB \-\-width\fR -Specify a width for a created window as a number or percentage. (default: 100%) -.TP \fB\-x\fR, \fB \-\-x-offset\fR Specify the x position for a created window as a number or percentage. (default: 0) .TP @@ -64,7 +64,7 @@ Specify flags/options that the terminal or program should be called with. For ex If there are available settings for the detected window manager for the -p, -P, -M, and/or -d options, automatically set them; takes no argument. User set settings will still override these. This can be used with 'tdrop ', 'tdrop auto_hide', and 'tdrop auto_show'. For 'auto_hide', if the window manager is supported, it will check if the current window is tiled so that it is not changed to floating when auto-showing. (default: false) .TP \fB\-m\fR, \fB \-\-monitor-aware\fR -This option only applies for dropdowns (not auto-hiding and auto-showing). Specify that width and height percentages should be relative to the current monitor. If the monitor changes, this option will cause a dropdown to be resized to fit the given percentages. A negative argument is also allowed for '-w' and '-y' with this option (e.g. '-m -w -4') in which case the determined value will be that many pixels less than 100% of the screen size. This fixes the problem where 100% width may actually go over the screen due to window borders/decoration. Note that this option assumes xrandr is being used and requires xrandr to work. (default: false) +This option only applies for dropdowns (not auto-hiding and auto-showing). Specify that geometry values should be relative to the current monitor. For example, if the width is a percentage or negative value, the pixel width will be calculated as a percentage of the current monitor's width (instead of the combined width of all monitors). If the monitor changes, this option will cause a dropdown to be resized to fit the given percentages. Note that this option assumes xrandr is being used and requires xrandr to work. (default: false) .TP \fB \-\-clear\fR Used to clear a saved window id for the given program or 'current' instead of creating a dropdown; takes no argument.