gtkdialog chooser

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#21 Post by MochiMoppel »

misko_2083 wrote:I guess the longer the sequence is, the longer it takes for xdotool to decode and type.
Yes, that's more or less what happens.
Whenever the dialog searches for filenames it creates a short lived process but it creates other short lived processes and it's difficult to figire which one is the right one. My idea was to detect when that short lived pricess ends.
I'm not sure if I understand what you mean. The search process itself is no problem. Problem is to figure out when the dialog is ready to begin the search and another problem is to feed the correct filename.
I guess the only way to do it right is to write a new gtk file selection dialog
:lol: I agree but that's not an option for me.

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#22 Post by misko_2083 »

MochiMoppel wrote:
Whenever the dialog searches for filenames it creates a short lived process but it creates other short lived processes and it's difficult to figire which one is the right one. My idea was to detect when that short lived pricess ends.
I'm not sure if I understand what you mean. The search process itself is no problem. Problem is to figure out when the dialog is ready to begin the search and another problem is to feed the correct filename.
The dialog is ready when: the mentioned short-lived process, that lists dir/files and populates the tree view exits. In most cases it's so short-lived that it even does not list in top (or htop).

So this requires strace

Code: Select all

#!/bin/bash
#Purpose: Find suitable delay for xdotool. Make chooser (re)start with a specified file
#Usage:
#1) Select a file in the chooser widget
#2) Press Restart button. This should restart the script with the last file selected
#3) Repeat steps 1 and 2 with different file in different directory to see if this works reliably.

FILESPEC=$(</tmp/lastdir)
STARTDIR=${FILESPEC%/*}
FILENAME=${FILESPEC##*/}
[[ -d $STARTDIR ]] || STARTDIR=/
 echo -n "$FILENAME" | xclip -loops 1 -sel c   #send basename to clipboard 
CLASSNAME="MochikaMopelka_FileChoser"

printf '
<window>
<vbox>
   <chooser>
      <variable>vCHOOSER</variable>
      <width>500</width><height>400</height>
      <default>"'"$STARTDIR"'"</default>
   </chooser>
   <button label="Restart">
      <action>printf "$vCHOOSER" > /tmp/lastdir ; exec "$(realpath "'$0'")" &</action>
      <action>exit:</action>
   </button>
</vbox>
</window>'  | gtkdialog -s --sync --class="$CLASSNAME" & pid=$!

# Wait here for the right line from strace
# Execute xdotool when the line contains one of "write", "pool", "recvmsg" or  "brk" just after the line containing "+++ exited with 0 +++"
# brk in about 1% of the cases, I hope I covered all the cases so far
# Edit: "strace -e signal=all" option is required after all
strace -e signal=all -ff -p $pid 2>&1 | grep --line-buffered -A 1 -E "exited with 0" 2>&1 |
while read -r line ; do
   # echo "$line"         # This line is for debbuging purposes
   if [[ "$line" =~ "write" || "$line" =~ "poll" || "$line" =~ "recvmsg" || "$line" =~ "brk" ]]; then
        xdotool search --sync --onlyvisible --class "$CLASSNAME" key comma BackSpace Shift+Insert Escape
        break
    fi
done

# wait returns exit code of the gtkdialog
wait $pid
echo $?

exit
Does it works on your end?

Edit: in /usr/bin there are telnet.netkit and telnet files.
If I select telnet then telnet.netkit is selected next time :shock:
It was all for nothing, even if I type in "telnet" it selects "telnet.netkit"
see the img
Attachments
telnet.gif
(55.08 KiB) Downloaded 235 times

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#23 Post by misko_2083 »

It's working preety well here.
Except maybe we should kill strace when the dialog is closed.

Strace can get stuck sometimes.
Perhaps one "killall strace" before exit? :)

Overall, if you look away from that issue with similar file names, it's working on deb 8 as you can see:
Image

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#24 Post by MochiMoppel »

misko_2083 wrote:Does it works on your end?
Once in a while.

Here one of my luckier moments: Aready the 4th attempt to reselect /bin/awk was successful. Normally in only one out of around 10 attempts the if condition matches.

Code: Select all

vCHOOSER="/bin/awk"
EXIT=""
[pid 18959] execve("/bin/grep", ["grep", "--line-buffered", "-A", "1", "-E", "exited with 0"], [/* 52 vars */] <unfinished ...>
[pid 18958] mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb758a000
vCHOOSER="/bin/awk"
EXIT=""
0
--
[pid 18982] execve("/bin/grep", ["grep", "--line-buffered", "-A", "1", "-E", "exited with 0"], [/* 52 vars */] <unfinished ...>
[pid 18981] stat64("/usr/bin/strace", {st_mode=S_IFREG|0755, st_size=208376, ...}) = 0
vCHOOSER="/bin/awk"
EXIT=""
0
--
[pid 19003] execve("/bin/grep", ["grep", "--line-buffered", "-A", "1", "-E", "exited with 0"], [/* 52 vars */] <unfinished ...>
[pid 19002] getegid32()                 = 0
vCHOOSER="/bin/awk"
EXIT=""
0
--
[pid 19024] execve("/bin/grep", ["grep", "--line-buffered", "-A", "1", "-E", "exited with 0"], [/* 52 vars */]) = 0
[pid 19024] brk(0)                      = 0x8099000

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#25 Post by misko_2083 »

MochiMoppel wrote:
misko_2083 wrote:Does it works on your end?
Once in a while.

Here one of my luckier moments: Aready the 4th attempt to reselect /bin/awk was successful. Normally in only one out of around 10 attempts the if condition matches.
Sorry to hear that.
You can try to grep a line before and one line after and see if there is some logic.

Code: Select all

{ strace -e signal=all -ff -p $pid 2>&1; }  | grep --line-buffered -A 1 -B 1 -E "exited with 0" 2>&1
#without the folowing while loop
What also works for me if I find "_exit(0)" in the line before "+++ exited with 0 +++" :

Code: Select all

#!/bin/bash
#Purpose: Find suitable delay for xdotool. Make chooser (re)start with a specified file
#Usage:
#1) Select a file in the chooser widget
#2) Press Restart button. This should restart the script with the last file selected
#3) Repeat steps 1 and 2 with different file in different directory to see if this works reliably.

FILESPEC=$(</tmp/lastdir)
STARTDIR=${FILESPEC%/*}
FILENAME=${FILESPEC##*/}
[[ -d $STARTDIR ]] || STARTDIR=/
 echo -n "$FILENAME" | xclip -loops 1 -sel c   #send basename to clipboard 
CLASSNAME="MochikaMopelka_FileChoser"

printf '
<window>
<vbox>
   <chooser>
      <variable>vCHOOSER</variable>
      <width>500</width><height>400</height>
      <default>"'"$STARTDIR"'"</default>
   </chooser>
   <button label="Restart">
      <action>killall strace & wait $! ; printf "$vCHOOSER" > /tmp/lastdir ; exec "$(realpath "'$0'")" &</action>
      <action>exit:</action>
   </button>
</vbox>
</window>'  | gtkdialog -s --sync --class="$CLASSNAME" & pid=$!

# we search for the "_exit(0)" or "+++ exited with 0 +++"
{ strace -e signal=all -ff -p $pid 2>&1; }  | grep --line-buffered -B 1 -E "exited with 0" 2>&1 |
while read -r line ; do
   echo $line
   if [[ "$line" =~ "_exit(0)" || "$line" =~ "+++ exited with 0 +++" ]]; then
        xdotool search --sync --onlyvisible --class "$CLASSNAME" type "$FILENAME"
        break
   fi
done

killall strace

wait $pid

echo $?

exit

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#26 Post by MochiMoppel »

Never enters the while loop, let alone the if condition. Amazing that it works for you :lol:

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#27 Post by MochiMoppel »

I decided to go back to my original approach, using the slow and shaky xdotool type. Using xclip doesn't bother me but using the clipboard does. IMO an application should never use the clipboard for temporary data storage, so I'd better do what I preach and stay away from it.

As a precaution against malfunction I set generous sleep values, depending on the number of items in the chooser tree.
Works for me with a test folder containing 5000 files.

Code: Select all

#!/bin/bash-
FILESPEC=$(</tmp/lastdir) 
STARTDIR=${FILESPEC%/*} 
FILENAME=${FILESPEC##*/} 
[[ -d $STARTDIR ]] || STARTDIR=/

FNN=$(printf '%s\n' "${STARTDIR}"/* | wc -l)                                                #number of files/folders in chooser tree
((FNN<100)) && XTS=0.8 || { ((FNN<1000))&&XTS=1.5 ;} || { ((FNN<2000))&&XTS=2 ;} || XTS=2.5 #set sleep depending on number of tree items
(($(printf "$FILENAME"|wc -c) != ${#FILENAME} )) && XTD='--delay=200'                       #set extra delay for multibyte filenames
MAP_XDOTOOL="<action signal=\"map-event\">xdotool sleep $XTS  type $XTD  \"$FILENAME\" &&  xdotool  key Escape & </action>"

printf ' 
<window title="Restarted with '$FNN' files/folders. Sleep time:'$XTS' sec"> 
<vbox> 
<chooser> 
   <variable>vCHOOSER</variable> 
   <width>500</width><height>400</height> 
   <default>"'"$STARTDIR"'"</default> 
</chooser> 
<button label="Restart"> 
   <action>printf "$vCHOOSER" > /tmp/lastdir ; exec "$(realpath "'$0'")" &</action> 
   <action>exit:</action> 
</button> 
</vbox> 
'"$MAP_XDOTOOL"'
</window>' | gtkdialog -s

Post Reply