help showing active app name in touch bar

I've been using BTT for about a month now, so still new to all this. I'm not a programmer, but I like messing around with scripting from time to time. I don't really know what I'm doing.

I'm trying to make my touch bar display the name of the frontmost active window. I'm trying to basically mirror the system menu bar on my touch bar -- then I can hide the menu bar to give me some extra screen space without loosing any of the key info that it provides.

Here's the button as I have it configured now. It doesn't work quite right. It's a "Shell Script / Task Widget" in my Touch Bar.

activeApp=$(lsappinfo info -only name `lsappinfo front` | sed -n 's/^.*"."//p' | sed 's/.$//')

(osascript <<EOF
    tell application "BetterTouchTool"
    	update_touch_bar_widget "01ECFDFA-CED3-496C-B5A6-5901A266B010" text "$activeApp"
    	refresh_widget "01ECFDFA-CED3-496C-B5A6-5901A266B010"
end tell
EOF
)

I'll give a breakdown of what I was trying to do...

This shell command gets the name of the frontmost application and formats it properly.

lsappinfo info -only name `lsappinfo front` | sed -n 's/^.*"."//p' | sed 's/.$//'

It works when I run it in Terminal. And when I attach this snippet to a BTT Shell Script widget, it works, but it doesn't update quick enough when I change apps. (I have the BTT Touch Bar configured to stay hidden until I press a modifier key, via the advanced Touch Bar setting checkbox "Allow keyboard modifiers to restore a hidden touch bar when they are pressed.") This widget's checkbox "Always run when widget becomes visible" is checked, but it's still too slow.

On to the next part.

I believe this AppleScript code should help the widget react more quickly and responsively. But instead, it breaks the button when I add it to the script. Instead of showing the application name normally, it starts flickering incredibly fast, and then the button vanishes from the touch bar after a moment or two.

tell application "BetterTouchTool"
    	update_touch_bar_widget "01ECFDFA-CED3-496C-B5A6-5901A266B010" text "$activeApp"
    	refresh_widget "01ECFDFA-CED3-496C-B5A6-5901A266B010"
end tell

Is there a better way to do this? I know I could run it all in AppleScript instead of Shell. But it seemed like that was even slower.

tell application "System Events"
   set frontmostProcess to first process where it is frontmost
   set appName to name of frontmostProcess
end tell

return appName

tell application "BetterTouchTool"
   update_touch_bar_widget "BDAE1084-0BF5-436F-99D7-1C441AC6CD20" text appName
refresh_widget "BDAE1084-0BF5-436F-99D7-1C441AC6CD20"
end tell

Thanks for any help!

Maybe this can help a little. The script show how to subscribe an event for changing the application. This allows you to call your trigger only when the application is changed.

You can test it in the Script Editor and finally save it as a script file and load it into the predefined trigger "After BTT has been started" with the action "Open application / File / Apple Script".

Note:
The observer runs during the application is running which executed the script file (in this case BTT or the Script Debugger).
If the script file is called multiple times, multiple observer instances will be created.

script theScript
	
	use AppleScript version "2.4" -- Yosemite (10.10) or later
	use framework "Foundation"
	use scripting additions
	
	property ca : current application
	property workspaceClass : class "NSWorkspace"
	
	on addObserver()
		set ws to workspaceClass's sharedWorkspace()
		set nc to ws's notificationCenter()
		tell nc to addObserver:me selector:"applicationDidActivate:" |name|:"NSWorkspaceDidActivateApplicationNotification" object:(missing value)
		--tell nc to removeObserver:me selector:"applicationDidActivate" |name|:"NSWorkspaceDidActivateApplicationNotification" object:(missing value)
	end addObserver
	
	on applicationDidActivate:theNSNotification
		set userInfo to theNSNotification's userInfo()
		set theApp to userInfo's valueForKey:(ca's NSWorkspaceApplicationKey)
		set theAppName to (theApp's localizedName()) as text
		
		display notification "Application did activate." with title theAppName

		-- write the application name into a BTT variable and call a named trigger
		tell application "BetterTouchTool"
			-- set BTT-Variable
			set_string_variable "ActiveApplication" to theAppName
			-- trigger the named trigger
			-- trigger_named "OnActivateApplication"
		end tell
		
		--- or use your trigger directly
		--tell application "BetterTouchTool"
		--	update_touch_bar_widget "BDAE1084-0BF5-436F-99D7-1C441AC6CD20" text theAppName
		--	refresh_widget "BDAE1084-0BF5-436F-99D7-1C441AC6CD20"
		--end tell

	end applicationDidActivate:
	
end script

theScript's addObserver()

Other idea:

BTT has a listener for NSWorkspaceDidActivateApplicationNotification on board:

If you then refresh the Touch Bar Button Widget at this event:

tell application "BetterTouchTool"
	refresh_widget "1A287D02-C5DC-40ED-A578-50DC4E30A96D"
end tell

and in this return the app name as JSON (not update the configuration!):

tell application "System Events"
	set frontmostProcess to first process where it is frontmost
	set appName to name of frontmostProcess
end tell
return "{\"text\":\"" & appName & "\"}"

then it works great.

But:
The included listener does not seem to work stable. After restarting BTT, there were no more events in my case, until I had saved the trigger again!

Either you use the listener from the previous post (and trigger the widget refresh in this), or you would have to write a bug report to Andreas.

Here is a preset of the triggers:

AppName.bttpreset (3.4 KB)

Note: If the event works, the update interval of the widget can and should be set to "0".