Automating Google Chrome Tab Refresh with a macOS Status Bar App

Automating Google Chrome Tab Refresh with a macOS Status Bar App

When you are a busy professional who relies heavily on real-time data from a specific website while managing multiple projects. With this AppleScript automation, you can effortlessly keep a vital Google Chrome tab refreshed without any manual effort, allowing you to focus on your work. Whether you're tracking market trends, monitoring social media feeds, or staying updated on project dashboards, this tool ensures you never miss out on crucial updates, enhancing your productivity and decision-making. Say goodbye to constant tab refreshing and hello to seamless multitasking!

This AppleScript automation is more secure than hundreds of Chrome extensions available on Chrome Web Store because it operates locally on your computer instead of relying on third-party software. It avoids potential security risks associated with extensions, such as data sharing with external servers or susceptibility to vulnerabilities in the extension's code. By keeping the process within your personal environment, you maintain greater control over your data and privacy.

Overview of Features

  • Status Bar Integration: The script creates a status bar item with a refresh icon (?) that can be interacted with to control the refresh functionality.
  • Tab Menu: It dynamically populates a menu with all open tabs in Google Chrome, allowing users to select which tab to refresh.
  • Pause/Resume Refresh: A toggle button in the menu pauses or resumes the refresh cycle.
  • Automatic Refresh: The script automatically refreshes the selected tab at regular intervals, which can be customized.

The Code

Below is the complete AppleScript code for the application:

use framework "Foundation"
use framework "AppKit"
use scripting additions

property refreshInterval : 10 -- Refresh interval in seconds
property refreshEnabled : true
property statusItem : missing value
property targetTabInfo : missing value -- Record with windowID and tabID of the selected tab
property targetTabTitle : "" -- Title of the selected tab
property tabMenuItems : {} -- List of menu items for tabs
property pauseMenuItem : missing value -- Reference to the Pause/Resume menu item
property refreshTimer : missing value -- NSTimer instance
property tabSubMenu : missing value -- Reference to the tab submenu

on run
	-- Create status bar item
	set statusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)
	statusItem's button's setTitle:"?"
	statusItem's setHighlightMode:true
	
	-- Create main menu
	set theMenu to current application's NSMenu's alloc()'s init()
	
	-- Add submenu for tabs
	set tabMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Select Tab" action:(missing value) keyEquivalent:""
	set tabSubMenu to current application's NSMenu's alloc()'s initWithTitle:"Tabs"
	tabMenuItem's setSubmenu:tabSubMenu
	theMenu's addItem:tabMenuItem
	
	-- Populate the tab submenu
	my updateTabMenuItemsInMenu:tabSubMenu
	
	-- Add other menu items
	-- Refresh Tab List
	set refreshMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Refresh Tab List" action:"refreshTabList:" keyEquivalent:""
	refreshMenuItem's setTarget:me
	theMenu's addItem:refreshMenuItem
	
	-- Pause/Resume
	set pauseMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Pause" action:"toggleRefresh:" keyEquivalent:""
	pauseMenuItem's setTarget:me
	theMenu's addItem:pauseMenuItem
	
	-- Quit
	set quitMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Quit" action:"quitApp:" keyEquivalent:""
	quitMenuItem's setTarget:me
	theMenu's addItem:quitMenuItem
	
	statusItem's setMenu:theMenu
	
	-- Start the refresh timer
	my startRefreshTimer()
end run

on startRefreshTimer()
	-- Invalidate existing timer if any
	if refreshTimer is not missing value then
		refreshTimer's invalidate()
	end if
	
	-- Schedule a new timer
	set refreshTimer to current application's NSTimer's scheduledTimerWithTimeInterval:refreshInterval target:me selector:"refreshPage:" userInfo:(missing value) repeats:true
end startRefreshTimer

on updateTabMenuItemsInMenu:theMenu
	-- Clear existing tab menu items
	theMenu's removeAllItems()
	set tabMenuItems to {}
	
	-- Collect open tabs
	tell application "Google Chrome"
		if it is running then
			set windowList to windows
			repeat with w in windowList
				set tabList to tabs of w
				repeat with t in tabList
					set tabTitle to (title of t)
					set tabURL to (URL of t)
					set menuItemTitle to tabTitle & " (" & tabURL & ")"
					set newMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:menuItemTitle action:"selectTabFromMenu:" keyEquivalent:"")
					-- Store window ID and tab ID
					set tabInfo to {windowID:(id of w), tabID:(id of t)}
					(newMenuItem's setRepresentedObject:tabInfo)
					(newMenuItem's setTarget:me)
					if targetTabInfo is not missing value and targetTabInfo's windowID = (id of w) and targetTabInfo's tabID = (id of t) then
						(newMenuItem's setState:(current application's NSControlStateValueOn))
					end if
					(theMenu's addItem:newMenuItem)
					-- Keep track of menu items
					set end of tabMenuItems to newMenuItem
				end repeat
			end repeat
		else
			-- Google Chrome is not running
			set newMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Google Chrome is not running" action:(missing value) keyEquivalent:""
			newMenuItem's setEnabled:false
			theMenu's addItem:newMenuItem
		end if
	end tell
end updateTabMenuItemsInMenu:

on selectTabFromMenu:sender
	-- Get the tab info (windowID and tabID) associated with the menu item
	set selectedTabInfo to sender's representedObject()
	set targetTabInfo to selectedTabInfo
	set targetTabTitle to sender's title()
	
	-- Update the menu items to reflect the selected tab
	repeat with menuItem in tabMenuItems
		if menuItem is sender then
			(menuItem's setState:(current application's NSControlStateValueOn))
		else
			(menuItem's setState:(current application's NSControlStateValueOff))
		end if
	end repeat
end selectTabFromMenu:

on refreshTabList:sender
	-- Update the tab submenu
	my updateTabMenuItemsInMenu:tabSubMenu
end refreshTabList:

on toggleRefresh:sender
	if refreshEnabled then
		set refreshEnabled to false
		sender's setTitle:"Resume"
		-- Invalidate the timer
		if refreshTimer is not missing value then
			refreshTimer's invalidate()
			set refreshTimer to missing value
		end if
	else
		set refreshEnabled to true
		sender's setTitle:"Pause"
		-- Restart the timer
		my startRefreshTimer()
	end if
end toggleRefresh:

on quitApp:sender
	-- Invalidate the timer
	if refreshTimer is not missing value then
		refreshTimer's invalidate()
	end if
	-- Terminate the application
	tell me to quit
end quitApp:

on refreshPage:theTimer
	if refreshEnabled and targetTabInfo is not missing value then
		tell application "Google Chrome"
			if it is running then
				try
					set targetWindow to missing value
					set targetTab to missing value
					set windowList to windows
					repeat with w in windowList
						if ((id of w) as string) = (targetTabInfo's windowID as string) then
							set targetWindow to w
							exit repeat
						end if
					end repeat
					if targetWindow is not missing value then
						set tabList to tabs of targetWindow
						repeat with t in tabList
							if ((id of t) as string) = (targetTabInfo's tabID as string) then
								set targetTab to t
								exit repeat
							end if
						end repeat
						if targetTab is not missing value then
							tell targetTab to reload
						else
							-- Tab not found
							set targetTabInfo to missing value
							set targetTabTitle to ""
							-- Update menu items to reflect that no tab is selected
							repeat with menuItem in tabMenuItems
								(menuItem's setState:(current application's NSControlStateValueOff))
							end repeat
						end if
					else
						-- Window not found
						set targetTabInfo to missing value
						set targetTabTitle to ""
						-- Update menu items to reflect that no tab is selected
						repeat with menuItem in tabMenuItems
							(menuItem's setState:(current application's NSControlStateValueOff))
						end repeat
					end if
				on error errMsg number errNum
					-- Handle unexpected errors
					set targetTabInfo to missing value
					set targetTabTitle to ""
					-- Update menu items to reflect that no tab is selected
					repeat with menuItem in tabMenuItems
						(menuItem's setState:(current application's NSControlStateValueOff))
					end repeat
				end try
			else
				-- Google Chrome is not running
				set targetTabInfo to missing value
				set targetTabTitle to ""
			end if
		end tell
	else
		-- No target tab selected or refresh is disabled; do nothing
	end if
end refreshPage:        

Running the Script

  1. Open Script Editor: Launch the Script Editor application on your Mac.
  2. Copy the Code: Paste the entire script into a new document.
  3. Save: Go to File > Export, choose Application as the file format, and check Stay Open After Run Handler.
  4. Run the App: Double-click the saved application to start it. The ? icon should appear in your menu bar.
  5. Select a Tab: Click the icon, navigate to Select Tab, and choose the tab you want to refresh automatically.
  6. Adjust Settings: Use the menu to pause/resume refreshing, refresh the tab list, or quit the application.


Screenshot of a running script

How It Works

Importing Frameworks

use framework "Foundation"
use framework "AppKit"
use scripting additions        

These lines import the necessary frameworks for macOS applications and scripting additions.

Property Definitions

property refreshInterval : 10 -- Refresh interval in seconds
property refreshEnabled : true
property statusItem : missing value
property targetTabInfo : missing value -- Record with windowID and tabID of the selected tab
property targetTabTitle : "" -- Title of the selected tab
property tabMenuItems : {} -- List of menu items for tabs
property pauseMenuItem : missing value -- Reference to the Pause/Resume menu item
property refreshTimer : missing value -- NSTimer instance
property tabSubMenu : missing value -- Reference to the tab submenu        

These properties store the state and configuration of the application, such as the refresh interval and references to UI elements.

on run Handler

on run
	-- Create status bar item
	...
end run        

This is the main entry point of the script. It sets up the menu bar icon, the menu items, and starts the refresh timer.

Creating the Status Bar Item

set statusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)
statusItem's button's setTitle:"?"
statusItem's setHighlightMode:true        

? Creates a new status bar item.

? Sets the icon to a refresh symbol (?).

? Enables highlight mode when clicked.

Setting Up the Menu

-- Create main menu
set theMenu to current application's NSMenu's alloc()'s init()        

Initializes the main menu for the status bar item.

Adding the Tab Selection Submenu

-- Add submenu for tabs
set tabMenuItem to current application's NSMenuItem's alloc()'s initWithTitle:"Select Tab" action:(missing value) keyEquivalent:""
set tabSubMenu to current application's NSMenu's alloc()'s initWithTitle:"Tabs"
tabMenuItem's setSubmenu:tabSubMenu
theMenu's addItem:tabMenuItem

-- Populate the tab submenu
my updateTabMenuItemsInMenu:tabSubMenu        

? Creates a submenu for selecting a Google Chrome tab.

? Populates the submenu with currently open tabs by calling updateTabMenuItemsInMenu:.

Adding Other Menu Items

-- Refresh Tab List
...

-- Pause/Resume
...

-- Quit
...        

Adds additional options to the menu:

? Refresh Tab List: Updates the list of tabs in case new ones have been opened or closed.

? Pause/Resume: Toggles the automatic refresh functionality.

? Quit: Exits the application.

Starting the Refresh Timer

on startRefreshTimer()
	-- Invalidate existing timer if any
	...
	
	-- Schedule a new timer
	...
end startRefreshTimer        

? Invalidates any existing timer.

? Creates a new NSTimer that calls refreshPage: at the specified interval.

Refreshing the Page

on refreshPage:theTimer
	if refreshEnabled and targetTabInfo is not missing value then
		...
	end if
end refreshPage:        

? Checks if refreshing is enabled and a target tab is selected.

? Uses AppleScript to tell Google Chrome to reload the selected tab.

? Handles cases where the tab or window might have been closed.

Updating the Tab List

on updateTabMenuItemsInMenu:theMenu
	-- Clear existing tab menu items
	...
	
	-- Collect open tabs
	...
end updateTabMenuItemsInMenu:        

? Clears the existing list of tabs in the submenu.

? Retrieves the list of open tabs from Google Chrome.

? Populates the submenu with the updated list.

Selecting a Tab

on selectTabFromMenu:sender
	-- Get the tab info (windowID and tabID) associated with the menu item
	...
	
	-- Update the menu items to reflect the selected tab
	...
end selectTabFromMenu:        

? Stores the selected tab’s information.

? Updates the menu to indicate which tab is currently selected.

Toggling Refresh

on toggleRefresh:sender
	if refreshEnabled then
		...
	else
		...
	end if
end toggleRefresh:        

? Toggles the refreshEnabled property.

? Updates the menu item title between “Pause” and “Resume”.

? Starts or stops the refresh timer accordingly.

Quitting the Application

on quitApp:sender
	-- Invalidate the timer
	...
	-- Terminate the application
	...
end quitApp:        

? Stops the timer.

? Quits the application.

Customization

  • Refresh Interval: Change the refreshInterval property at the top of the script to set a different refresh rate.

property refreshInterval : 30 -- Refresh every 30 seconds        

  • Icon: Modify the setTitle method for statusItem to change the menu bar icon.

statusItem's button's setTitle:"?"        

Conclusion

This AppleScript is a practical example of integrating Google Chrome management with macOS’s status bar functionality. It automates refreshing a Chrome tab, with features to pause, resume, and dynamically manage tab selection. You can customize the refresh interval or extend the functionality further to suit specific needs.

This also provides organizations a way to not depend on externally developed Chrome extensions for simple tasks.

要查看或添加评论,请登录

Rohit B.的更多文章

  • Building blocks of a zero trust journey - Part 2

    Building blocks of a zero trust journey - Part 2

    For Part 1 of the article, please refer here This article will focus on how different services explained in the part-1…

    2 条评论
  • Building blocks of a zero trust journey

    Building blocks of a zero trust journey

    Corporations small and large are starting to get tangled into this buzz word called "Zero Trust". What is Zero Trust?…

    5 条评论

社区洞察

其他会员也浏览了