diff --git a/README.md b/README.md
index 4f39fde..e41c28f 100644
--- a/README.md
+++ b/README.md
@@ -210,6 +210,7 @@ A special tag can be used as an alternative to refresh interval defined in plugi
#### Other Parameters
+* `#true` - refreshes plugin on click, before presenting the menu
* `false` - doesn't wrap plugins in Bash when running
* `streamable` - mark plugin as Streamable
* `[var1:default value, var2:default value, ... ]` - this variables will be passed in plugin's environment, in later release SwiftBar will provide a UI to change values for these variables.
diff --git a/SwiftBar/MenuBar/MenuBarItem.swift b/SwiftBar/MenuBar/MenuBarItem.swift
index 372a80a..fda1aca 100644
--- a/SwiftBar/MenuBar/MenuBarItem.swift
+++ b/SwiftBar/MenuBar/MenuBarItem.swift
@@ -92,7 +92,7 @@ class MenubarItem: NSObject {
contentUpdateCancellable = plugin?.contentUpdatePublisher
.receive(on: menuUpdateQueue)
.sink { [weak self] content in
- guard self?.isOpen == false else {
+ guard self?.isOpen == false, plugin?.metadata?.refreshOnOpen == true else {
self?.refreshOnClose = true
return
}
@@ -605,9 +605,31 @@ extension MenubarItem {
}
func showMenu() {
+ if plugin?.metadata?.refreshOnOpen == true, plugin?.type == .Executable {
+ refreshAndShowMenu()
+ return
+ }
barItem.menu = statusBarMenu
barItem.button?.performClick(nil)
}
+
+ func refreshAndShowMenu() {
+ if #available(macOS 11.0, *) {
+ barItem.button?.image = NSImage(systemSymbolName: "hourglass", accessibilityDescription: nil)
+ barItem.button?.imagePosition = .imageLeft
+ } else {
+ barItem.button?.image = nil
+ barItem.button?.title = "..."
+ }
+ DispatchQueue.main.async { [weak self] in
+ self?.barItem.button?.image = nil
+ self?.barItem.button?.title.removeAll()
+ self?.plugin?.refresh()
+ self?.updateMenu(content: self?.plugin?.content)
+ self?.barItem.menu = self?.statusBarMenu
+ self?.barItem.button?.performClick(nil)
+ }
+ }
@discardableResult func performItemAction(params: MenuLineParameters) -> Bool {
if let href = params.href, let url = URL(string: href) {
diff --git a/SwiftBar/Plugin/ExecutablePlugin.swift b/SwiftBar/Plugin/ExecutablePlugin.swift
index 3e7eb28..4e3b2de 100644
--- a/SwiftBar/Plugin/ExecutablePlugin.swift
+++ b/SwiftBar/Plugin/ExecutablePlugin.swift
@@ -148,8 +148,7 @@ class ExecutablePlugin: Plugin {
}
@objc func scheduledContentUpdate() {
- content = invoke()
- enableTimer()
+ refresh()
}
}
diff --git a/SwiftBar/Plugin/PluginMetadata.swift b/SwiftBar/Plugin/PluginMetadata.swift
index 1175b5a..41aaaf5 100644
--- a/SwiftBar/Plugin/PluginMetadata.swift
+++ b/SwiftBar/Plugin/PluginMetadata.swift
@@ -27,12 +27,13 @@ enum PluginMetadataOption: String, CaseIterable {
case hideSwiftBar
case environment
case runInBash
+ case refreshOnOpen
var optionType: [PluginMetadataType] {
switch self {
case .title, .version, .author, .github, .desc, .about, .image, .dependencies:
return [.bitbar, .xbar]
- case .runInBash, .environment, .droptypes, .schedule, .type, .hideAbout, .hideRunInTerminal, .hideLastUpdated, .hideDisablePlugin, .hideSwiftBar:
+ case .runInBash, .environment, .droptypes, .schedule, .type, .hideAbout, .hideRunInTerminal, .hideLastUpdated, .hideDisablePlugin, .hideSwiftBar, .refreshOnOpen:
return [.swiftbar]
}
}
@@ -57,6 +58,7 @@ class PluginMetadata: ObservableObject {
@Published var hideSwiftBar: Bool
@Published var environment: [String: String]
@Published var runInBash: Bool
+ @Published var refreshOnOpen: Bool
var isEmpty: Bool {
name.isEmpty
@@ -74,7 +76,7 @@ class PluginMetadata: ObservableObject {
return try? cron.next()
}
- init(name: String = "", version: String = "", author: String = "", github: String = "", desc: String = "", previewImageURL: URL? = nil, dependencies: [String] = [], aboutURL: URL? = nil, dropTypes: [String] = [], schedule: String = "", type: PluginType = .Executable, hideAbout: Bool = false, hideRunInTerminal: Bool = false, hideLastUpdated: Bool = false, hideDisablePlugin: Bool = false, hideSwiftBar: Bool = false, environment: [String: String] = [:], runInBash: Bool = true) {
+ init(name: String = "", version: String = "", author: String = "", github: String = "", desc: String = "", previewImageURL: URL? = nil, dependencies: [String] = [], aboutURL: URL? = nil, dropTypes: [String] = [], schedule: String = "", type: PluginType = .Executable, hideAbout: Bool = false, hideRunInTerminal: Bool = false, hideLastUpdated: Bool = false, hideDisablePlugin: Bool = false, hideSwiftBar: Bool = false, environment: [String: String] = [:], runInBash: Bool = true, refreshOnOpen: Bool = false) {
self.name = name
self.version = version
self.author = author
@@ -93,6 +95,7 @@ class PluginMetadata: ObservableObject {
self.hideSwiftBar = hideSwiftBar
self.environment = environment
self.runInBash = runInBash
+ self.refreshOnOpen = refreshOnOpen
}
var shouldRunInBash: Bool {
@@ -109,6 +112,9 @@ class PluginMetadata: ObservableObject {
let closeTag = "\(prefix).\(tag.rawValue)>"
return script.slice(from: openTag, to: closeTag)
}
+ if tag == .refreshOnOpen {
+ print(values)
+ }
return values.last ?? ""
}
@@ -149,7 +155,9 @@ class PluginMetadata: ObservableObject {
hideDisablePlugin: getTagValue(tag: .hideDisablePlugin) == "true",
hideSwiftBar: getTagValue(tag: .hideSwiftBar) == "true",
environment: environment,
- runInBash: getTagValue(tag: .runInBash) == "false" ? false : true)
+ runInBash: getTagValue(tag: .runInBash) == "false" ? false : true,
+ refreshOnOpen: getTagValue(tag: .refreshOnOpen) == "true" ? true: false
+ )
}
static func parser(fileURL: URL) -> PluginMetadata? {
@@ -215,6 +223,8 @@ class PluginMetadata: ObservableObject {
value = environment.map { "\($0.key):\($0.value)" }.joined(separator: ",")
case .runInBash:
value = runInBash ? "" : "false"
+ case .refreshOnOpen:
+ value = refreshOnOpen ? "true" : ""
}
guard !value.isEmpty else { return }
let tag = option