You are not logged in.

#61 2015-11-11 23:13:20

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

@Sector11

I just copied your conky code and ran it with

conky -c "/home/damo/.config/conky/conky Test/conkyrc1"

It worked fine, and after the move (to the right monitor) the conkyrc was changed to:

#conkymove, original value for gap_x: 120
gap_x 2008
#conkymove, original value for gap_y: 10
gap_y 55

alignment tl

Obvious question is:    Do you have `/usr/bin/xdotool` & `/usr/bin/xwininfo` present?


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#62 2015-11-11 23:24:21

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

Incorporated these changes, and improved the dialog messages:

#!/bin/bash
##
#   Script to set the position of a moveable Conky
#
#   Written by damo <damo@bunsenlabs.org> November 2015
#   with major contributions of functions, commands and suggestions by @johnraff

DIALOG="yad --center --undecorated --borders=20 \
--window-icon=/usr/share/pixmaps/Bunsenlabs-flame-256.svg"

unset CONKYPATH posX_1 posY_1 posX_2 posY_2 OFFSET_X OFFSET_Y gapX gapY

# makes array "config"
parse_conkyfile(){   # function by @johnraff
    [[ -f $1 ]] || { echo "$1 is not a file." >&2;return 1;}
    unset config
    declare -Ag config
    local name value
    while read name value
    do
        [[ $name ]] || continue
        [[ $name = TEXT* ]] && break
        config["$name"]="$value"
    done < <(sed 's/\#.*$//' "$1")
}


# usage: edit_conkyfile file name=value [name2=value2...]
# use absolute path to file
# parse_conkyfile should already have been run
edit_conkyfile() {  # function by @johnraff, improved by xaos52
    [[ "$1" = /* ]] || {
        echo "$0: $1 is not an absolute path." >&2
        return 1
    }
    file=$1
    shift
    local name value
    declare -ag sed_args
    while [[ $1 ]]; do
        unset name value sed_pattern sed_replace
        name="${1%%=*}"
        value="${1#*=}"
        shift
        [[ ${config["$name"]+x} ]] || {
            echo "$0: config key $name does not exist" >&2
            return 1
        }
        [[ ${config["$name"]//[[:space:]]} = "${value//[[:space:]]}" ]] && continue
        (( ${#sed_args[@]} == 0 )) && sed_args=("-ri")
        sed_pattern="^ *$name .*$"
        grep -q "#conkymove, original value for $name:" "$file" ||
            sed_replace="#conkymove, original value for $name: ${config[$name]}\n"
        sed_replace+="$name $value"
        sed_args+=("-e")
        sed_args+=("s/$sed_pattern/$sed_replace/")
    done
    (( ${#sed_args[@]} )) && sed "${sed_args[@]}" "$file"
}

function getStart(){    #   Get initial Conky position
    unset CONKYPATH
    unset info1
    declare -A info1
    while read line
    do
        unset key value
        [[ $line =~ Window\ id: ]] && {
            ID=${line#*id:}
            ID=${ID% \"*}
        }
        [[ $line != xwininfo:* && $line = *:* ]] && {
            key=${line%:*}
            value=${line#*:}
            info1[$key]=$value
        }
    done < <(xwininfo)
    # info now contains all the output of xwininfo

    # command suggested by @johnraff....
    #CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' '{cmd=$1;sub(/^.*{ "/,"",cmd);for (i=1;i<=NF;i++)if($i=="-c"){i++;sub(/\" }$/,"",$i);gsub(/\\\"/,"\"",$i);print cmd,$i;exit}}')
    CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' '{cmd=$1;sub(/^.*{ "/,"",cmd);for (i=1;i<=NF;i++)if($i ~ /-([a-zA-Z])?c/){i++;sub(/\" }$/,"",$i);gsub(/\\\"/,"\"",$i);print cmd,$i;exit}}')

    if [[ ${CMD%% *} = conky ]];then
        echo "Found a conky"
        CONKYPATH=${CMD#* }
        posX_1=${info1[Absolute upper-left X]}
        posY_1=${info1[Absolute upper-left Y]}
    else
        echo "Selection is not a conky"
        $DIALOG --button="OK:0" --text="Selection is not a conky\n\nChoose again"
        getStart
    fi
}

function getFinish(){   #   Get new Conky position
    unset info2
    declare -A info2
    while read line
    do
        unset key value
        [[ $line != xwininfo:* && $line = *:* ]] && {
            key=${line%:*}
            value=${line#*:}
            info2[$key]=$value
        }
    done < <(xwininfo -id $ID)
    posX_2=${info2[Absolute upper-left X]}
    posY_2=${info2[Absolute upper-left Y]}
}

function getOffset(){   # parse_conkyfile should already have been run
    if [[ ${config[alignment]} = none ]];then   # placement managed by Openbox
        TXT="This Conky has 'alignment none'\nso placement is handled by the Window Manager.\n"
        $DIALOG --text="$TXT" --button="OK"
        echo -e "\nConky has 'alignment none',\nso placement is handled by the Window Manager\nExiting...\n"
        exit 0
    fi

    OFFSET_X=$(( posX_2 - posX_1 ))
    OFFSET_Y=$(( posY_2 - posY_1 ))

    case ${config[alignment]} in
        tr|top_right|mr|middle_right|br|bottom_right|mm|middle_middle|bm|bottom_middle|tm|top_middle)
            gapX=$(( ${config[gap_x]} - OFFSET_X ))
            ;;
        tl|top_left|ml|middle_left|bl|bottom_left)
            gapX=$(( ${config[gap_x]} + OFFSET_X ))
            ;;
    esac
    case ${config[alignment]} in
        tr|top_right|tl|top_left|tm|top_middle)
            gapY=$(( ${config[gap_y]} + OFFSET_Y ))
            ;;
        br|bottom_right|bl|bottom_left|bm|bottom_middle|mm|middle_middle|ml|middle_left|mr|middle_right)
            gapY=$(( ${config[gap_y]} - OFFSET_Y ))
            ;;
    esac
}

$DIALOG --text="Click 'Select Conky' to pick a conky.\n\nThen use the 'xdotool' cursor on the chosen conky\nto record its position." \
     --button="Select Conky:0" --button="gtk-cancel:1"

if (( $? == 0 ));then
    getStart
else
    echo "  Cancelled: exiting..."
    exit 0
fi

$DIALOG --text="Move the Conky to the desired location\nthen click 'OK' to set the new position." \
     --button="OK:0" --button="gtk-cancel:1"

if (( $? == 0 ));then
    getFinish
else
    echo "  Cancelled: exiting..."
    exit 0
fi

parse_conkyfile "$CONKYPATH"

getOffset

edit_conkyfile "$CONKYPATH" "gap_x"=$gapX "gap_y"=$gapY

exit 0

Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#63 2015-11-12 12:40:44

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,668
Website

Re: Movable conkys

@Doctor Xaos thanks for the reminder about read -r, it's something I forget to put in sometimes.

re - your refactoring of that awk process in bash - awk is in fact rather well suited to splitting strings by multi-character delimiters: even the Bash Wiki says "If your field delimiter is a multi-character string, then unfortunately bash does not offer any simple ways to deal with that. Your best bet is to handle the task in awk instead."

Unfortunately, IFS can not be set to a multi-character string - word-splitting will be done on any of the characters in IFS.

Thanks for this reminder:

# conky command. can be conky, /usr/bin/conky, usr/local/bin/conky, ...

icon_redface.gif

I was intrigued by your idea of converting the comma-space strings to newlines though. Can I suggest extending the substituted string to the double-quotes at each end? That way you don't have to remove them later. The leading and trailing quotes can also be removed along with the braces. ie, I would suggest:

 cmd_file=$(xprop -id ${win[id]}  WM_COMMAND)
        [[ "$cmd_file" == *not\ found* ]] && {
            echo "ID:${win[id]} - $cmd_file"
            continue
        }
        # remove prefix up to the double-quote after the opening { and space
        cmd_file=${cmd_file#*\{ \"}
        # remove suffix quote, space and closing }
        cmd_file=${cmd_file%\" \}}
        # replace every occurrence of '", "' by a new_line
        cmd_file=${cmd_file//\", \"/$'\n'}
        # then these two lines are not needed:
        #entry=${entry#\"}
        #entry=${entry%\"}

This is also slightly more robust: config filepaths containing quote-comma-space-comma will break it, as opposed to the slightly more possible comma-space. In both cases a filepath containing a newline will break it too. (I do feel that awk might be the better tool for the job in this case though.) In fact, I'm not sure if it's even possible to make a 100% foolproof way of breaking that output of xprop into its individual arguments that would work for filepaths containing any of the permitted unix characters (ie anything except a forward slash).

@damo thanks for spotting that bug with -qc options, and for the fix. Some time soon we also have to cater for --config= type options. neutral

Do you have `/usr/bin/xdotool` & `/usr/bin/xwininfo` present?

Bit of copy-paste code to avoid having to ask that:

required_commands=(xdotool xwininfo) # array, space-separated words

error_exit() {
    echo "$0 error: $1" >&2
    exit 1
}

missing_commands=()
for i in "${required_commands[@]}"
do
    hash $i || missing_commands+=(" $i")
done
[[ ${missing_commands[0]} ]] && error_exit "This script requires the following commands: ${missing_commands[*]}
Please install the packages containing the missing commands
and rerun the script."

(String required_commands changed to array because xaos52 is watching.)

I'll give the shiny new script a run tommorow on my BL testbed with a bunch of conkys. It looks good though. smile


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#64 2015-11-12 12:58:34

xaos52
The Good Doctor
From: Planet of the @pes
Registered: 2015-09-30
Posts: 695

Re: Movable conkys

You are right. awk is the appropriate tool here.
On top of that, the awk solution is faster than the one I proposed.
Lesson learned: using an external command that requires subprocess creation is not always faster than using bash features. Always benchmark, your intuition might be wrong.
Thx for the lesson, John. smile

Offline

#65 2015-11-13 02:59:53

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,668
Website

Re: Movable conkys

xaos52 wrote:

using an external command that requires subprocess creation is not always faster slower than using bash features.

Fixed it for you. smile

To be honest, I was astonished how fast awk was the first time I used it.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#66 2015-11-13 12:41:21

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

johnraff wrote:

@damo thanks for spotting that bug with -qc options, and for the fix. Some time soon we also have to cater for --config= type options. neutral

...and "--config=" can't have any whitespace before the conky path sad


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#67 2015-11-13 12:59:25

xaos52
The Good Doctor
From: Planet of the @pes
Registered: 2015-09-30
Posts: 695

Re: Movable conkys

Should the script be able to cope with all possible variations to launch a conky?
Like:

conky
conky -c /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -qdc  /home/me/.config/conky/test\ conky/the\ special\ one
conky /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -q -c /home/me/.config/conky/test\ conky/the\ special\ one -d

If that is the case, then the awk script will have to implement something like the 'gnu-options' feature.
I am sure it can be done, but the awk script will need to be able to handle more complexity than it does now.
Else we will have to limit ourselves to accepted options, and mention it that we don't support all possible combinations, no?

Offline

#68 2015-11-13 13:26:20

xaos52
The Good Doctor
From: Planet of the @pes
Registered: 2015-09-30
Posts: 695

Re: Movable conkys

Here is a test script that handles above mentioned variations:

#!/usr/bin/env bash

# accfs is acronym for 'active conky configuration files'
get_accfs() {
    unset win
    declare -A win
    accfs=()
    PARSER='
{
        cmd=$1
        sub(/^.*{ "/,"",cmd)
        sub(/\" }$/,"",cmd)
        for (i=2;i<=NF;i++) {
                sub(/\" }$/,"",$i)
                gsub(/\\\"/,"\"",$i)
                if ($i ~ /-([a-zA-Z]*)?c/)
                {
                        i++
                        sub(/\" }$/,"",$i)
                        gsub(/\\\"/,"\"",$i)
                        print cmd,$i
                        exit
                }
                else {
                        if ($i !~ /-*/)
                        {
                                print cmd,$i
                                exit
                        }
                }
        }
        print cmd
}
'    
    while read win[id] win[desktop] win[xoffset] win[yoffset] win[width] win[height] win[client] win[title]
    do
        local cmd_file index_cfgfile i 
        [[ ${win[title]} = *[Cc]onky* ]] || continue
        ID=${win[id]}
        CMD=$(xprop -id $ID  WM_COMMAND)
        CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' "$PARSER")            
        if grep "conky" <<< $CMD &>/dev/null;then
            echo "Found a conky"
            CONKYPATH=${CMD#* }
            [[ "$CONKYPATH" == "$CMD" ]] && CONKYPATH="$HOME/.conkyrc"
            accfs+=("${CONKYPATH}")
        fi
    done < <(wmctrl -lG)
}

pkill -KILL conky
sleep 1

# start some conky's
conky
conky -c /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -qdc  /home/me/.config/conky/test\ conky/the\ special\ one
conky /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -q -c /home/me/.config/conky/test\ conky/the\ special\ one -d

sleep 1
pgrep conky

time get_accfs
printf '\n'
printf 'active conky config files:\n'
printf '%s\n' "${accfs[@]}"

Offline

#69 2015-11-13 18:08:44

xaos52
The Good Doctor
From: Planet of the @pes
Registered: 2015-09-30
Posts: 695

Re: Movable conkys

Modified the logic slightly.
Now works for --config also.

#!/usr/bin/env bash

# accfs is acronym for 'active conky configuration files'
get_accfs() {
    unset win
    declare -A win
    accfs=()
    PARSER='
{
        sub(/^.*{ "/,"",$1)
        sub(/\" }$/,"",$1)
        cmd=$1
        for (i=2;i<=NF;i++) {
                sub(/\" }$/,"",$i)
                gsub(/\\\"/,"\"",$i)
                if (match($i, /^--config=/,m)) {
                        print cmd,substr($i,RLENGTH+1)
                        exit
                }
                else
                        if (match($i, /^[-]/,m))  continue
                        else {
                                j=i-1
                                if (j == 1) {
                                        print cmd,$i
                                        exit
                                }
                                else {
                                        if (match($j, /-([A-Za-z])*)?c/,m)) {
                                                print cmd,$i
                                                exit
                                        }
                                        else
                                                continue
                                }
                        }
        }
        print cmd
}
'    
    while read win[id] win[desktop] win[xoffset] win[yoffset] win[width] win[height] win[client] win[title]
    do
        local cmd_file index_cfgfile i 
        [[ ${win[title]} = *[Cc]onky* ]] || continue
        ID=${win[id]}
        CMD=$(xprop -id $ID  WM_COMMAND)
        [[ "$CMD" == *not\ found* ]] && {
            echo "ID:${win[id]} - $CMD"
            continue
        }
        CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' "$PARSER")            
        if grep "conky" <<< $CMD &>/dev/null;then
            echo "Found a conky"
            CONKYPATH=${CMD#* }
            [[ "$CONKYPATH" == "$CMD" ]] && CONKYPATH="$HOME/.conkyrc"
            accfs+=("${CONKYPATH}")
        fi
    done < <(wmctrl -lG)
}

pkill -KILL conky
sleep 1

# start some conky's
conky
conky -c /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -qdc  /home/me/.config/conky/test\ conky/the\ special\ one
conky /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -q -c /home/me/.config/conky/test\ conky/the\ special\ one -d
conky -q --config=/home/me/.config/conky/test\ conky/the\ special\ one -d

sleep 1
pgrep conky

time get_accfs
printf '\n'
printf 'active conky config files:\n'
printf '%s\n' "${accfs[@]}"

Offline

#70 2015-11-14 03:04:14

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,668
Website

Re: Movable conkys

@xaos52 your input is always greatly appreciated, but:

xaos52 wrote:

Should the script be able to cope with all possible variations to launch a conky?
Like:

conky
conky -c /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -qdc  /home/me/.config/conky/test\ conky/the\ special\ one
conky /home/me/.config/conky/test\ conky/the\ \"special\"\ one
conky -q -c /home/me/.config/conky/test\ conky/the\ special\ one -d

The awk script as-is already handles all strange unix-accepted characters in filenames except newlines, which few sane (or honest) people would want to use, and deals with arguments before or after the -c filepath pair. Damo's bugfix enables options like -qc, and with my suggested modification (below) also handles -qdc etc. The third example you post above ('conky filepath') is not compatible with conky's syntax.
So, for example:

john@raffles4:/data/john/projects/conkymove$ ls
conky_check.sh  "conkyrc-caption"  It's called "conkyrc-caption"
conkymove.sh    conkyrc-caption    It's called "conkyrc-caption", "so?"
conkypin        conkyrc-cap"tion
john@raffles4:/data/john/projects/conkymove$ conky -qbc "$PWD"/It\'s\ called\ \"conkyrc-caption\"\,\ \"so\?\" -d 
john@raffles4:/data/john/projects/conkymove$ wmctrl -l
0x01200003 -1 raffles4 Desktop
0x044000b0  0 raffles4 Post a reply / BunsenLabs Linux Forums - Iceweasel
0x01802f8b  0 raffles4 conkymove - File Manager
0x04600009  0 raffles4 john@raffles4: /data/john/projects/conkymove
0x04800009  0 raffles4 john@raffles4: ~
0x01600002 -1 raffles4 Conky test
john@raffles4:/data/john/projects/conkymove$ i=0x01600002
john@raffles4:/data/john/projects/conkymove$ xprop -id $i  WM_COMMAND
WM_COMMAND(STRING) = { "conky", "-qbc", "/data/john/projects/conkymove/It's called \"conkyrc-caption\", \"so?\"", "-d" }
john@raffles4:/data/john/projects/conkymove$ xprop -id $i  WM_COMMAND | awk -F '", "' '{cmd=$1;sub(/^.*{ "/,"",cmd);for (i=1;i<=NF;i++)if($i ~ /-[a-z]*c$/){i++;sub(/\" }$/,"",$i);gsub(/\\\"/,"\"",$i);print cmd,$i;exit}}'
conky /data/john/projects/conkymove/It's called "conkyrc-caption", "so?"

So, with the greatest respect, we're pretty much there already. (You did actually test the existing awk script, right?) I'll add the --config option soon.

Last edited by johnraff (2015-11-14 04:22:59)


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#71 2015-11-14 03:13:20

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,668
Website

Re: Movable conkys

@damo a tweak to your regex to enable options like -qbc and make sure c comes last. Replace

/-([a-z])?c/

with

/-[a-z]*c$/

(The extra () round the [] were unnecessary.)

EDIT in fact:

/^-[a-z]*c$/

Last edited by johnraff (2015-11-14 07:33:07)


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#72 2015-11-14 03:32:18

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

Yeah, regex is an unfamiliar minefield for me. I was basically following similar examples I found wink

(Don't forget there are some uppercase switches for Conky as well)

Last edited by damo (2015-11-14 03:33:25)


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#73 2015-11-14 04:32:58

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 12,668
Website

Re: Movable conkys

damo wrote:

(Don't forget there are some uppercase switches for Conky as well)

Oh yes, thanks! (Dr xaos had that covered already.)

Anyway, that one-liner is getting impossible to read so I'm following xaos52's example and putting it in a PARSER variable, which now looks like this:

    PARSER='{
        cmd=$1
        sub(/^.*{ "/,"",cmd)
        for (i=2;i<=NF;i++){
            found=0
            if($i ~ /^-[a-zA-Z]*c$/ || $i == "--config"){
                i++
                found=1
            }
            if($i ~ /^--config=/){
                sub(/^--config=/,"",$i)
                found=1
            }
            if(found == 1){
                sub(/\" }$/,"",$i)
                gsub(/\\\"/,"\"",$i)
                print cmd,$i
                exit
            }
        }
    }'

and can be plugged into the script the same way xaos52 did it:

awk -F '", "' "$PARSER"

I think it covers all the possibilities, and seems to be working.

Last edited by johnraff (2015-11-14 04:35:08)


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )

Introduction to the Bunsenlabs Boron Desktop

Offline

#74 2015-11-14 15:22:24

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

^
I had already done my own "readability" version, with

   CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' '{
       cmd=$1
       sub(/^.*{ "/,"",cmd)
       for (i=1;i<=NF;i++)
        if($i ~ /-([a-zA-Z])?c/){
            i++
            sub(/\" }$/,"",$i)
            gsub(/\\\"/,"\"",$i)
            print cmd,$i
            exit
            }
       }'

Your latest version is working on the conkys and filepaths I've tested so far smile


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#75 2015-11-14 16:18:30

damo
....moderator....
Registered: 2015-08-20
Posts: 6,734

Re: Movable conkys

Latest script I'm using is...

#!/bin/bash
#
#   Script to set the position of a moveable Conky
#
#   Written by @johnraff and @damo
#   with major contributions by @xaos52

# array to hold necessary tools
required_commands=(xwininfo xprop yad)

DIALOG="yad --center --undecorated --borders=20 \
--window-icon=/usr/share/pixmaps/Bunsenlabs-flame-256.svg"

unset CONKYPATH posX_1 posY_1 posX_2 posY_2 OFFSET_X OFFSET_Y gapX gapY

# makes array "config"
parse_conkyfile(){   # function by @johnraff
    [[ -f $1 ]] || { echo "$1 is not a file." >&2;return 1;}
    unset config
    declare -Ag config
    local name value
    while read name value
    do
        [[ $name ]] || continue
        [[ $name = TEXT* ]] && break
        config["$name"]="$value"
    done < <(sed 's/\#.*$//' "$1")
}

# usage: edit_conkyfile file name=value [name2=value2...]
# use absolute path to file
# parse_conkyfile should already have been run
edit_conkyfile() {  # function by @johnraff, improved by xaos52
    [[ "$1" = /* ]] || {
        echo "$0: $1 is not an absolute path." >&2
        return 1
    }
    file=$1
    shift
    local name value
    declare -ag sed_args
    while [[ $1 ]]; do
        unset name value sed_pattern sed_replace
        name="${1%%=*}"
        value="${1#*=}"
        shift
        [[ ${config["$name"]+x} ]] || {
            echo "$0: config key $name does not exist" >&2
            return 1
        }
        [[ ${config["$name"]//[[:space:]]} = "${value//[[:space:]]}" ]] && continue
        (( ${#sed_args[@]} == 0 )) && sed_args=("-ri")
        sed_pattern="^ *$name .*$"
        grep -q "#conkymove, original value for $name:" "$file" ||
            sed_replace="#conkymove, original value for $name: ${config[$name]}\n"
        sed_replace+="$name $value"
        sed_args+=("-e")
        sed_args+=("s/$sed_pattern/$sed_replace/")
    done
    (( ${#sed_args[@]} )) && sed "${sed_args[@]}" "$file"
}

function getStart(){    # Get initial Conky position
    unset CONKYPATH
    unset info1
    declare -A info1
    while read line
    do
        unset key value
        [[ $line =~ Window\ id: ]] && {
            ID=${line#*id:}
            ID=${ID% \"*}
        }
        [[ $line != xwininfo:* && $line = *:* ]] && {
            key=${line%:*}
            value=${line#*:}
            info1[$key]=$value
        }
    done < <(xwininfo) # info1 now contains all the output of xwininfo

    # parse conky command by @johnraff....
    PARSER='{
        cmd=$1
        sub(/^.*{ "/,"",cmd)
        for (i=2;i<=NF;i++){
            found=0
            if($i ~ /^-[a-zA-Z]*c$/ || $i == "--config"){
                i++
                found=1
            }
            if($i ~ /^--config=/){
                sub(/^--config=/,"",$i)
                found=1
            }
            if(found == 1){
                sub(/\" }$/,"",$i)
                gsub(/\\\"/,"\"",$i)
                print cmd,$i
                exit
            }
        }
    }'
    # and use it with...
    CMD=$(xprop -id $ID  WM_COMMAND | awk -F '", "' "$PARSER")

    if [[ ${CMD%% *} = conky ]];then
        echo "Found a conky"
        CONKYPATH=${CMD#* }
        posX_1=${info1[Absolute upper-left X]}
        posY_1=${info1[Absolute upper-left Y]}
    else
        echo "Selection is not a conky"
        $DIALOG --button="OK:0" --button="Exit:1" --text="Selection is not a conky\n\nChoose again?"
        if (( $? == 1 ));then
            echo "  Cancelled: exiting..."
            exit 0
        fi
        getStart
    fi
}

function getFinish(){   # Get new Conky position
    unset info2
    declare -A info2
    while read line
    do
        unset key value
        [[ $line != xwininfo:* && $line = *:* ]] && {
            key=${line%:*}
            value=${line#*:}
            info2[$key]=$value
        }
    done < <(xwininfo -id $ID)
    posX_2=${info2[Absolute upper-left X]}
    posY_2=${info2[Absolute upper-left Y]}
}

function getOffset(){   # parse_conkyfile should already have been run
    if [[ ${config[alignment]} = none ]];then   # placement managed by Openbox
        TXT="This Conky has 'alignment none'\nso placement is handled by the Window Manager.\n"
        $DIALOG --text="$TXT" --button="OK"
        echo -e "\nConky has 'alignment none',\nso placement is handled by the Window Manager\nExiting...\n"
        exit 0
    fi

    OFFSET_X=$(( posX_2 - posX_1 ))
    OFFSET_Y=$(( posY_2 - posY_1 ))

    case ${config[alignment]} in
        tr|top_right|mr|middle_right|br|bottom_right|mm|middle_middle|bm|bottom_middle|tm|top_middle)
            gapX=$(( ${config[gap_x]} - OFFSET_X ))
            ;;
        tl|top_left|ml|middle_left|bl|bottom_left)
            gapX=$(( ${config[gap_x]} + OFFSET_X ))
            ;;
    esac
    case ${config[alignment]} in
        tr|top_right|tl|top_left|tm|top_middle)
            gapY=$(( ${config[gap_y]} + OFFSET_Y ))
            ;;
        br|bottom_right|bl|bottom_left|bm|bottom_middle|mm|middle_middle|ml|middle_left|mr|middle_right)
            gapY=$(( ${config[gap_y]} - OFFSET_Y ))
            ;;
    esac
}

function error_exit() {
    echo -e "$0 error:\n  $1" >&2
    exit 1
}

missing_commands=()
for i in "${required_commands[@]}"
do
    hash $i || missing_commands+=(" $i")
done
[[ ${missing_commands[0]} ]] && error_exit "This script requires the following commands:  ${missing_commands[*]}\n\nPlease install the packages containing the missing commands
and rerun the script...\n"

$DIALOG --text="Click 'Select Conky'...\n\nThen use the 'xwininfo' cursor to pick a conky\nand record its position." \
     --button="Select Conky:0" --button="gtk-cancel:1"

if (( $? == 0 ));then
    getStart
else
    echo "  Cancelled: exiting..."
    exit 0
fi

$DIALOG --text="Move the Conky to the desired location\nwith 'Alt+L-button+Drag'...\n\nThen click 'OK' to set the new position." \
     --button="OK:0" --button="gtk-cancel:1"

if (( $? == 0 ));then
    getFinish
else
    echo "  Cancelled: exiting..."
    exit 0
fi

parse_conkyfile "$CONKYPATH"

getOffset

edit_conkyfile "$CONKYPATH" "gap_x"=$gapX "gap_y"=$gapY

exit 0

Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

Board footer

Powered by FluxBB