Last application running before mine activates

tell application "System Events" to set applist to displayed name of every application process where it is not background only

returns a list of windowed applications currently running. They appear, I believe, in the order in which they were launched.

I want to click my app in the dock and work with the app that was running when I launched mine.
i.e. if I was browsing in Safari, if writing a letter in TextEdit and so on.

Is it possible to know which application this was?

Thanks.

Hello.

Not sure if this is what you are after, but it sure does activate the previous app. :slight_smile:

 tell application "System Events"
	keystroke tab using command down
	keystroke return
end tell

Hello.

Personally I prefer something like this, that just puts the frontmost window of the previous active app,
on top of the app that I’m currently in.
It isn’t perfect, but it works, for me at least, without any ado. :slight_smile:

-- Copyright © 2013 McUsr
script recap
	property parent : AppleScript
	script o
		property bundl_nms : missing value
		property proc_nms : missing value
	end script
	on run
		local e, toget, recapped, foundFrontmost
		set {recapped, foundFrontmost} to {false, false}
		
		tell application id "com.apple.systemevents"
			set {o's bundl_nms, o's proc_nms} to {bundle identifier, name} of (every process whose visible is true)
			repeat while not foundFrontmost
				repeat with i from 1 to count o's proc_nms
					if item i of o's proc_nms is not missing value and (count every window of (application process (item i of o's proc_nms))) = 0 then ¬
						set item i of o's proc_nms to missing value
					
					if item i of o's proc_nms is not missing value and (frontmost of (application process (item i of o's proc_nms))) = true then
						
						if recapped is false then
							set visible of (application process (item i of o's proc_nms)) to false
							set e to item i of o's proc_nms
							set recapped to true
							exit repeat
						else
							set visible of (application process e) to true
							set toget to item i of o's bundl_nms
							set foundFrontmost to true
							exit repeat
						end if
					end if
				end repeat
			end repeat
		end tell
		do shell script "open -b " & toget
		
	end run
end script
run script recap

If at times should doubt the psychic abilities of the script above, then the script below could maybe suite your taste:

-- Elevate http://macscripter.net/viewtopic.php?pid=154619#p154619
-- © McUsr and put into public domain
property parent : AppleScript

script elevate
	property parent : AppleScript
	on run
		script o
			property a : missing value
			property b : missing value
		end script
		local a, b, c, d, i
		tell application id "com.apple.systemevents"
			set {o's a, o's b} to {bundle identifier, name} of (every process whose visible is true)
			
			repeat with i from 1 to count o's b
				
				if (count every window of (application process (item i of o's b))) = 0 then
					set {item i of o's a, item i of o's b} to {missing value, missing value}
				else if (frontmost of (application process (item i of o's b))) = true then
					set e to item i of o's b
					set {item i of o's a, item i of o's b} to {missing value, missing value}
				end if
			end repeat
		end tell
		set {o's a, o's b} to {o's a's text, o's b's text}
		tell application id "com.apple.systemuiserver"
			activate
			set c to (choose from list o's b default items item 1 of o's b with title "Elevate a window")
		end tell
		
		if c = false then
			tell application e to activate
			error number -128
		end if
		set d to indexOfItem(c, o's b)
		do shell script "open -b " & item d of o's a
		
	end run
	
	on indexOfItem(theItem, itemsList)
		-- credit to Emmanuel Levy 
		local rs
		
		set text item delimiters to return
		set itemsList to return & itemsList & return
		set text item delimiters to {""}
		try
			set rs to -1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in itemsList) of itemsList)))
		on error
			return 0
		end try
		rs
	end indexOfItem
end script
run script elevate

Hi McUsrII

Thanks for that.

The first suggestion works perfectly. I think I’ll go with that.
The only problem might be if Apple were to change the command tab shortcut (but I am pretty confident that they are not likely to do that soon)
There must be a “recent applications list” sorted by most recent first to be able to work that, and that is what System Events is reading I guess.
It would be interesting to know where that list is so that we could read it directly.

The second script, if I have understood it correctly:

  1. finds the list of all running visible processes
  2. filters out the ones which are windowless
  3. checks each qualifying process and makes it invisible if not the frontmost and loops again
  4. on the next loop if the process is still visible it is the one we wanted
  5. that process is brought up to the front

The third brings to the front any app that you choose from the list.
I am designing a background app that does a chore and quits and I do not need the list.

Thanks again for your very useful suggestions.

Hello.

I think you’ll have a hard time finding that list by AppleScript at least, and it wouldn’t surprise me, if it was hard to get at with Cocoa too, unless you use Apple’s private api’s. The only ways I can think of, is by the two techniques used in the two first scripts I posted.

The second script is not perfect if you have windows from several apps open at the moment.I think I have an idea for figuring it out, and if I’m bored to death tomorrow, I’ll see if I can present one such solution, that are both fast and leaves the displays as untarnished as possible.

I don’t know that there is any such list. System Events is probably asking NSWorkspace for runningApplications, and the documentation for that says: “The order of the array is unspecified, but it is stable, meaning that the relative order of particular apps will not change across multiple calls”.

I’m quite sure that I tested before a way to bring the last frontmost process to the front, but I can’t find the script. Come to think of it, I think it went like this. Run the new process, then set its frontmost to false. I think that brought the last process to the front.

I’ll try looking for the script. I might have lost it in an update or Automator workflow which I forgot to backup.

gl,
kel

Hello kel.

I have a permutation of that above (first script post #3), which gets the second frontmost process in the current space/desktop.

I won’t follow up on doing that script correctly, because that is far outside of AppleScript, and using private Api’s (they still work), isn’t particularily nice anyway. It may also be slow, since I am not sure if I can get at the z-ordering of the windows.

Thanks Shane and kel1,
Your input is much appreciated…

look here what I found thanks to a McUsr post Last edited by McUsr (2012-08-14 04:30:40 am)
http://macscripter.net/viewtopic.php?id=11884


tell application "System Events"
	tell (first application process whose frontmost is true)
		set visible of it to false
		set active_name to name of it
	end tell
	set Name_App to item 1 of (get name of processes whose frontmost is true and visible is true)
end tell
tell application active_name
	activate
	display dialog "previous active app: " & Name_App
end tell

Here’s a script that lets you choose a process or window to bring to the front.

-- SEChooseProcessWindow
property the_prompt : "Choose a process or window:"
--
set my_name to name of me
tell application "System Events"
	-- show hidden processes
	set visible of every process to true
	-- get list of processes
	set process_list to name of every process whose visible is true and name is not my_name
end tell
-- create list of processes and their windows
set user_list to {}
set i to 0
repeat with this_process in process_list
	set i to i + 1
	set end of user_list to ((i as string) & tab & (contents of this_process))
	tell application "System Events"
		set window_list to name of every window of process this_process
	end tell
	repeat with this_window in window_list
		set end of user_list to ((i as string) & tab & tab & (contents of this_window))
	end repeat
end repeat
-- user chooses a process or window
activate
set user_choice to (choose from list user_list with prompt the_prompt) as string
if user_choice is "false" then error number -128 -- user canceled
set process_index to word 1 of user_choice -- string
set user_process to item process_index of process_list
-- bring to front
tell application "System Events"
	tell process user_process
		set frontmost to true
		if user_choice contains (tab & tab) then
			set user_window to (text ((count process_index) + 3) thru -1 of user_choice)
			tell window user_window
				perform action "AXRaise"
			end tell
		end if
	end tell
end tell
return
-- Notes:
-- Some processes may not have the same name as the application.

Had help from McUsr with the AXRaise.

gl,
kel

Hello.

I think I learned the AXRaise command of StefanK or Yvan Koenig, or maybe Nigel Garvey.

I’m having a hard time making applets that use UIScripting work under Mavericks, most of them has been converted back to scripts. Not only are they trouble some to make to work, when they work, they do so sloowly, compared to the script alternative. :slight_smile:

Well it appears there is. But actually using __LSCopyApplicationArrayInFrontToBackOrder is another matter altogether.

Hello.

Thanks a lot. :slight_smile: It is still not straight forward to get it “right”, but I think its a huge step in the right direction.

Hello.

I was pondering this last night, and this is an attempt to get it mostly right to be run as a script since it uses System Events and UI Scripting.

This is set up for when I am using 3 apps at the same time, and wants the window of the fourth, anybody using this may of course be happy with three windows, or two.

I haven’t figured out a way to make this work more perfectly, without using a modifier key to reset the counter, so that you could have run, gotten the first window of first process that is not frontmost , rerun, gotten the first window of the second process that wasn’t frontmost, etc.

Well, it shouldn’t be necessary those days with those scripts, given mission control and all, that makes it so easy, save the times you use the bad graphichs card for saving battery.

P.S

I have discovered that if you drag the mouse twice fast down to the edge of the screen, then the Dock becomes responsive. :slight_smile:


script recap
	-- Takes advantage of the fact thatthe last process in the list is the active one
	property parent : AppleScript
	property max_apps : 4
	script o
		property proc_nms : missing value
	end script
	on run
		local ctr
		set ctr to 1
		
		tell application id "com.apple.systemevents"
			set o's proc_nms to name ¬
				of (every process whose visible is true)
			
			repeat with i from 1 to ((length of o's proc_nms) - 1)
				
				if item i of o's proc_nms is not missing value ¬
					and (count every window of (application process (item i of o's proc_nms))) = 0 then
					
					set item i of o's proc_nms to missing value
				else
					tell application process (item i of o's proc_nms) ¬
						to tell its window 1 to perform action "AXRaise"
					
					set ctr to ctr + 1
					if ctr ≥ max_apps then exit repeat
				end if
			end repeat
		end tell
	end run
end script
run script recap