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
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
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
property refreshInterval : 30 -- Refresh every 30 seconds
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.