Size and Arrange All Windows of an Application?

(This community is so helpful to me. I hope I can learn enough, or stumble across enough newbie questions, that I can give half as much back.)

Every week I have to open dozens of Screenflow documents (in batches of about 10 at a time) and then copy down their running times (see image 1 below). Screenflow, however, is quirky about its document windows. The first two usually open in the monitor's bottom left corner while the rest cascade more or less nicely, but not always the same size. Manually fixing the sizing and arrangement becomes pretty annoying dealing with a few dozen--sometimes in excess of 100--of these every week.

I need to have all those document windows resized to the same size and, if at all possible, arranged cascaded neatly and in reverse order so that I can see their bottom bars with the times (like image 2 below ).

Is this even possible? If so, could you please tell me how?

Image 1: What I have and don't want.

Image 2: What I want.

Just a thought :blush: — if your goal is to get and/or list the durations that show in the status bar of each window, does the program provide another way to get the information other than human-reading it and inputting it manually?

Further: if you specify what you need further downstream for input into another process, it is likely that some here can provide suggestions for a more direct and robust workflow. What are you doing with the numbers representing “duration” once you have them? Why do you need to have the windows arranged so you can see all the status bars but only one content area and title bar?

Whenever you want to deal with a list of things (windows in this case), you need a For Each action.

Keyboard Maestro includes a WINDOWCOUNT function, and the Manipulate a Window action can move or resize the indexed window.

So a relatively simple solution that just moves the windows to the top left corner, arrayed diagonally would be this:

For Each.kmactions (1.3 KB)

Or if you want to move and resize the windows to full size, use something like this:

Keyboard Maestro Actions.kmactions (1.9 KB)

That did it! Thank you very much!

Not that I can find.

I need to list out all the times in a spreadsheet that automatically tallies them into hours and minutes.

Hey Pariah,

Run this AppleScript from the Applescript Editor.app with a bunch of windows open in ScreenFlow:

set winNameAndDurationList to {}

tell application "System Events"
  tell application process "ScreenFlow"
    set winList to windows whose subrole is "AXStandardWindow"
    repeat with theWin in winList
      tell theWin
        set winTitle to title
        set winDuration to value of static text 1
        set end of winNameAndDurationList to (winTitle & tab & winDuration)
        
      end tell
    end repeat
  end tell
end tell

winNameAndDurationList

You'll get an AppleScript list of tab-delimited Window-Title and Duration for each window.

Give me more information on how you want to manage the data, and I can change the output to suit.

-Chris

Wow! Thanks, Chris.

I get the below error when running that script, though.

The ultimate destination for the data is an Excel spreadsheet (screenshot below). It would be fantastic if you could have it produce a tab-delimited document with title, 3 blank tabs, minutes, and then seconds.

Hey Pariah,

Okay, try this one. It will skip items where there is an error.

set winNameAndDurationList to {}

tell application "System Events"
  tell application process "ScreenFlow"
    set winList to windows whose subrole is "AXStandardWindow"
    repeat with theWin in winList
      try
        tell theWin
          set winTitle to title
          set winDuration to value of static text 1
          set end of winNameAndDurationList to (winTitle & tab & winDuration)
        end tell
      end try
    end repeat
  end tell
end tell

winNameAndDurationList

-Chris

Hey Pariah,

That should be doable.

Are you creating new worksheets?

Or are you adding data to an existing worksheet?

-Chris

Thanks, Chris.

They’re going into an existing worksheet, so just putting them on the clipboard ready for pasting into the spreadsheet would be great.

Hey Pariah,

Try this.

Run from an Execute an AppleScript action with the “ignore results” option.

Paste as desired.

-Chris

--------------------------------------------------------------------------------------
# Auth: Christopher Stone { Liberal help with ASObjC by Shane Stanley }
# dCre: 2016/05/12 23:00 CST
# dMod: 2016/05/25 22:30 CST
# Appl: ScreenFlow & System Events
# Task: Produce a tab-delimited list of titles and durations for ScreenFlow documents.
# Aojc: True
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @System_Events
--------------------------------------------------------------------------------------
# For Pariah Burke on the Keyboard Maestro forum
--------------------------------------------------------------------------------------
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------------

# Line format: Title, 3 blank tabs, minutes, and then seconds.

set winNameAndDurationList to {}

tell application "System Events"
  tell application process "ScreenFlow"
    set winList to windows whose subrole is "AXStandardWindow"
    set AppleScript's text item delimiters to {"Duration: ", "secs"}
    repeat with theWin in winList
      try
        tell theWin
          set winTitle to title
          set winDuration to value of static text 1
          set end of winNameAndDurationList to (winTitle & tab & tab & tab & winDuration)
        end tell
      end try
    end repeat
  end tell
end tell

set winNameAndDurationList to joinList(winNameAndDurationList, linefeed)
set winNameAndDurationList to its cngStr:"Duration: *" intoString:"" inString:winNameAndDurationList
set winNameAndDurationList to its cngStr:"(mins) *" intoString:"$1	" inString:winNameAndDurationList

set the clipboard to winNameAndDurationList

--------------------------------------------------------------------------------------
--» HANDLERS
--------------------------------------------------------------------------------------
on cngStr:findString intoString:replaceString inString:dataString
  set anNSString to current application's NSString's stringWithString:dataString
  set dataString to (anNSString's ¬
    stringByReplacingOccurrencesOfString:findString withString:replaceString ¬
      options:(current application's NSRegularExpressionSearch) range:{0, length of dataString}) as text
end cngStr:intoString:inString:
--------------------------------------------------------------------------------------
on joinList(ListToJoin, deLimiter)
  set oldTIDS to AppleScript's text item delimiters
  set AppleScript's text item delimiters to deLimiter
  set joinedList to ListToJoin as string
  set AppleScript's text item delimiters to oldTIDS
  return joinedList
end joinList
--------------------------------------------------------------------------------------
1 Like

Fantastic! Thank you so much, Chris! It’s exactly what I needed.