Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort windows by last access time #5

Closed
klayman opened this issue Dec 20, 2014 · 16 comments
Closed

Sort windows by last access time #5

klayman opened this issue Dec 20, 2014 · 16 comments

Comments

@klayman
Copy link

klayman commented Dec 20, 2014

There is a point at which jumpapping loses to alt-tabbing. When I work on a project I often has to switch between an editor and some pdf-documents in evince. With swift alt-tabbing I always get the most recent accessed pdf-document. When I use jumpapp evince I get the first (or, with -r option, the last) opened pdf-document. It's not so handy.

I think that it's possible to sort the list of windows returned by wmctrl -lpx by the last focus timestamp. Here is some code I googled from stackoverflow with minor edits:

XTIME="_NET_WM_USER_TIME" # a shorter name for xprop query that shoul return timestamps
export TMPDIR=/dev/shm    # save tmp files to memory to make it faster
LST=`mktemp`              # tmp file to store our listing 
wmctrl -lx |  awk -F' ' '{printf("%s\t%s    \t",$1,$3); for(i=5;i<=NF;i++) printf("%s",$i); printf("\n")  }'  > $LST # pretty-print our listing of windows into the tmp file
 # To each line of listing, prepend a timestamp acquired via an xprop call
 # Use awk to find a line whose 3rd column (winclass) matches the window class "evince.Evince" and among those that do, find the one whose timestamp is the largest
while read LINE; do ID=`echo "$LINE"|cut -f 1`; TIME=`xprop -id $ID $XTIME`;  TIME="${TIME/* = /}"; echo -e "$TIME\t$LINE" ; done <$LST | awk -v s="evince.Evince" '$3 == s {if($1>max){max=$1;line=$0};};END{print line}'
rm $LST  # delete tmp file
@mkropat
Copy link
Owner

mkropat commented Dec 20, 2014

Good idea! That should probably be the default behavior, and if not, at the very least be an option.

No promises about time frame, but I'll see if I can put something together in the next week or two.

@mkropat
Copy link
Owner

mkropat commented Jan 17, 2015

I'm still working on this btw in my free time and I want to see this happen. Might be another month or two before I get it done though :)

@klayman
Copy link
Author

klayman commented Aug 28, 2015

Meantime I have found a workaround - a separate python script that returns the sorted list instead of the wmctrl -lpx output:

#!/usr/bin/env python
# encoding: UTF-8
#
# This is a simple script for sorting the wmctrl -lpx output by a last focus timestamp
import subprocess

# obtaining the list of windows initially sorted by the creation timestamp
wlist = subprocess.check_output( 'wmctrl -lpx', shell = True )

wlist = wlist.splitlines()

# getting the focus timestamp by the window id
def focustime( line ):
    time = subprocess.check_output( 'xprop -id ' + line.split()[ 0 ] + ' _NET_WM_USER_TIME', shell = True )
    if len( time.split( ' = ' ) ) > 1:
        time = time.split( ' = ' )[ 1 ]
    else:
        time = '0'
    return time

# using the focus timestamp as a sorting key
wlist.sort( key = focustime )

print( "\n".join( wlist ) )

Sure, it is possible to make the same in the jumpapp script directly, but I'm not good at bash. For now I only changed the line in list_windows() to call this python script instead of wmctrl -lpx.

@mkropat
Copy link
Owner

mkropat commented Aug 28, 2015

Cool! Working code helps, even if it's in a different language.

How's the speed with that script in place? My fear was that jumpapp would feel slow if it had to spawn another process for every process line, but maybe it's not so bad.

@klayman
Copy link
Author

klayman commented Aug 28, 2015

I didn't test it with many windows opened, but for a list of 10 processes there may be a slight delay, I think less than 0.1 s - it's almost unnoticeable. And there is a huge usability improvement in some workflows.

mkropat added a commit that referenced this issue Aug 29, 2015
@mkropat
Copy link
Owner

mkropat commented Aug 29, 2015

Do you want to help me test the beta version of this functionality? I've created a new branch for my development work: sort-by-access

If you already have the git repo cloned, you can test it with:

git fetch
git checkout sort-by-access
make && sudo make install

The code still needs a little polish, but I just wanted to get your thoughts about behavior + performance.

@klayman
Copy link
Author

klayman commented Aug 30, 2015

Strange, but your code does not work for me. Only for Opera browser windows I get the expected behaviour, but for sakura, mucommander and atril (evince fork) jumpapping doesn't differ from the old (master branch) behaviour.

@mkropat
Copy link
Owner

mkropat commented Aug 30, 2015

Good to know. Thanks for testing. My guess is that the window access time logic isn't working on your desktop. Two questions:

  1. What window manager are you using? Maybe I can reproduce it locally
  2. From the branch again, can you run jumpapp -L NAME with NAME as a program that works (like Opera) and with NAME as a program that doesn't sort correctly (like sakura)?

The first column of output should be the window last access time, so if it's 0 or some other non-valid value, that would explain why it's not working.

@klayman
Copy link
Author

klayman commented Aug 31, 2015

  1. Currently I use openbox WM.
  2. Yes, you are right. Here is the output for Opera:
393620798 0x02c000b3 localhost 31234 0 Opera: Developer Tools - https://mail.google.com/mail/u/0/ - Opera
393600258 0x02c00001 localhost 31234 0 Opera: Re: [jumpapp] Sort windows by last access time (#5) - Gmail - Opera

and for sakura:

0 0x05600007 localhost 23839 0 Sakura: ~
0 0x05000007 localhost 12021 0 Sakura: scripts

That said, xprop -id ######## _NET_WM_USER_TIME works fine for sakura and others.

@mkropat
Copy link
Owner

mkropat commented Sep 1, 2015

Think I figured it out: Openbox does not support _NET_WM_USER_TIME_WINDOW. Jumpapp needs to check _NET_WM_USER_TIME_WINDOW first, however, otherwise it won't work on Cinnamon (the window manager I use). As a workaround in case the _NET_WM_USER_TIME_WINDOW value is a lie (as seems to be the case in Openbox), Jumpapp will now fall back to trying _NET_WM_USER_TIME on the original window.

Do you mind testing out the latest code? If you still have it checked out you can do:

git pull --ff-only
make && sudo make install

@klayman
Copy link
Author

klayman commented Sep 1, 2015

It works, thank you!

@klayman klayman closed this as completed Sep 1, 2015
@mkropat
Copy link
Owner

mkropat commented Sep 1, 2015

Cool, I need to clean up the code then I'll put together a new release with this change.

If people complain about it being noticeably slower, I may have to make the new sorting optional, but I only plan to do that if people actually give feedback about it.

@ghost
Copy link

ghost commented Jan 28, 2016

Have you done it? It's not working for me..

@mkropat
Copy link
Owner

mkropat commented Jan 29, 2016

Unfortunately, no. I only implemented a prototype. It would be really useful though, so give me a few weeks and I'll see if I can get the latest changes merged into the prototype, and add unit tests.

@mkropat mkropat reopened this Jan 29, 2016
@markolenik
Copy link

Thanks for the enhancement, works in gnome!

@mkropat
Copy link
Owner

mkropat commented Apr 12, 2016

This feature just got released with the good work done in #13 and #14. Try it out and feel free to open a new issue if you find problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants