diff --git a/twander.py b/twander.py index 7a8ff95..8f87134 100755 --- a/twander.py +++ b/twander.py @@ -4,7 +4,7 @@ PROGNAME = "twander" -RCSID = "$Id: twander.py,v 1.82 2002/11/25 23:06:48 tundra Exp $" +RCSID = "$Id: twander.py,v 1.83 2002/11/26 18:58:30 tundra Exp $" VERSION = RCSID.split()[2] @@ -13,6 +13,7 @@ #----------------------------------------------------------# import getopt +import mutex import os from socket import getfqdn from stat import * @@ -143,6 +144,7 @@ MB = KB * KB # 1 MB constant GB = MB * KB # 1 GB constant HOSTNAME = getfqdn() # Full name of this host +POLLINT = 20 # Interval (ms) the poll routine should run REFRESHINT = 2000 # Interval (ms) for automatic refresh @@ -545,8 +547,20 @@ def poll(self): - RefreshDirList() - self.DirList.after(REFRESHINT, self.poll) + # If new dir entered via mouse, force correct activation + if self.MouseNewDir: + self.DirList.activate(0) + self.MouseNewDir = FALSE + + # See if its time to do a refresh + + self.ElapsedTime += POLLINT + if self.ElapsedTime >= REFRESHINT: + RefreshDirList() + self.ElapsedTime = 0 + + # Setup next polling event + self.DirList.after(POLLINT, self.poll) # End of method 'twanderUI.poll()' @@ -789,6 +803,8 @@ ##### def DirListHandler(event): + global UI + SAVE = TRUE # Get current selection. If none, just return, otherwise process @@ -832,15 +848,22 @@ # Load UI with new directory LoadDirList(selected, save=SAVE) - # And always force selection of first item there. - # This guarantees a selection in the new - # directory context, so subsequent commands - # won't try to operate on an item selected in a - # previous directory - - KeySelTop(event) + # Indicate that we entered a new directory this way. + # This is a workaround for Tk madness. When this + # routine is invoked via the mouse, Tk sets the + # activation *when this routine returns*. That means + # that the activation set at the end of LoadDirList + # gets overidden. We set this flag here so that + # we can subsequently do the right thing in our + # background polling loop. Although this routine + # can also be invoked via a keyboard selection, + # we run things this way regardless since no harm + # will be done in the latter case. - # File selected with a double-click + UI.MouseNewDir = TRUE + + + # No, a *file* was selected with a double-click # If we're running Win32, use OS association to try and run it. elif OSNAME == 'nt': @@ -901,6 +924,11 @@ # And select new directory to visit UI.CurrentDir = newdir + # Wait until we have exclusive access to the widget + + while not UI.DirListMutex.testandset(): + pass + # Clear out the old contents UI.DirList.delete(0,END) @@ -911,11 +939,17 @@ # And update the title to reflect changes UI.UpdateTitle(UIroot) - # Indicate that we've just entered a new directory - # so RefreshDirList does the right thing + # And always force selection of first item there. + # This guarantees a selection in the new + # directory context, so subsequent commands + # won't try to operate on an item selected in a + # previous directory - UI.NewDirEntered = TRUE - + KeySelTop(None) + + #Release the lock + UI.DirListMutex.unlock() + # End of 'LoadDirList(): @@ -1080,10 +1114,14 @@ def RefreshDirList(*args): + # Wait until we have exclusive access to the widget + + while not UI.DirListMutex.testandset(): + pass + # Get current selection and active sellist = UI.DirList.curselection() - active = UI.DirList.index(ACTIVE) # Save current scroll positions @@ -1091,39 +1129,30 @@ xs = UI.hSB.get() ys = UI.vSB.get() - # Get new directory listing - newlist = BuildDirList(UI.CurrentDir) - # Clean out old listbox contents UI.DirList.delete(0,END) # Save the new directory information - UI.DirList.insert(0, *newlist) + UI.DirList.insert(0, *BuildDirList(UI.CurrentDir)) - # First refresh after a new directory - # entered needs to force selection and - # active to 0. This works around some - # strange Tkinter behavior. - - if UI.NewDirEntered: - KeySelTop(args) - UI.NewDirEntered = FALSE - - # Otherwise restore selections - else: - SetSelection(sellist, active) + # Restore selection(s) + SetSelection(sellist, active) # Restore scroll positions UI.DirList.xview(MOVETO, xs[0]) UI.DirList.yview(MOVETO, ys[0]) - + + # Release the mutex + UI.DirListMutex.unlock() # End of 'RefreshDirList() ##### # Set a particular selection, w/bounds checking +# Note that 'selection' is passed as a string +# but 'active' is passed as a number. ##### def SetSelection(selection, active): @@ -1149,7 +1178,6 @@ # Now set the active entry UI.DirList.activate(active) - # End of 'SetSelection()' @@ -1236,8 +1264,14 @@ # And current location UI.CurrentDir = "" -# And the flag indicating new directory selected -UI.NewDirEntered = FALSE +# Need mutex to serialize on widget updates +UI.DirListMutex = mutex.mutex() + +# Intialize the "new dir via mouse" flag +UI.MouseNewDir = FALSE + +# Initialize the polling counter +UI.ElapsedTime = 0 # Start in detailed mode UI.SetDetailedView(TRUE)