Skip to content

Commit c4bbc10

Browse files
committed
Add a startup activity for the status bar
Previously the Widget would need to be disabled/enabled after every restart due to the ExperimentalSettings flag not being available in memory when the StatusBarManager starts up. This registers a startup activity that only runs after the project (including the application level settings) have loaded. It also moves the settings watcher into this class to keep the Factory "pure". Lastly, default the widget to display as soon as the experimental setting is enabled. I think the setting used to be at project level, but it is now at application level, and it makes sense to me that if I enable it in Experimental Settings, it should immediately appear in the status bar.
1 parent 45b8223 commit c4bbc10

File tree

3 files changed

+53
-48
lines changed

3 files changed

+53
-48
lines changed

resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<statusBarWidgetFactory
3030
id="ElixirSdkStatus"
3131
implementation="org.elixir_lang.status_bar_widget.ElixirSdkStatusWidgetFactory"/>
32+
<backgroundPostStartupActivity implementation="org.elixir_lang.status_bar_widget.ElixirSdkStatusWidgetStartupActivity"/>
3233

3334
<!-- <errorHandler implementation="org.elixir_lang.errorreport.Submitter"/>-->
3435
<errorHandler implementation="com.intellij.diagnostic.JetBrainsMarketplaceErrorReportSubmitter"/>
Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
package org.elixir_lang.status_bar_widget
22

3-
import com.intellij.openapi.application.ApplicationManager
43
import com.intellij.openapi.diagnostic.logger
54
import com.intellij.openapi.project.Project
6-
import com.intellij.openapi.project.ProjectManager
75
import com.intellij.openapi.wm.StatusBar
86
import com.intellij.openapi.wm.StatusBarWidget
97
import com.intellij.openapi.wm.StatusBarWidgetFactory
10-
import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager
11-
import com.intellij.util.messages.MessageBusConnection
128
import org.elixir_lang.settings.ElixirExperimentalSettings
13-
import org.elixir_lang.settings.ElixirExperimentalSettingsListener
149

1510
private val LOG = logger<ElixirSdkStatusWidgetFactory>()
1611

1712
class ElixirSdkStatusWidgetFactory : StatusBarWidgetFactory {
18-
private var messageBusConnection: MessageBusConnection? = null
19-
20-
init {
21-
setupSettingsListener()
22-
}
23-
2413
override fun getId(): String = ElixirSdkStatusWidget.ID
2514

2615
override fun getDisplayName(): String = "Elixir SDK Status"
@@ -45,41 +34,8 @@ class ElixirSdkStatusWidgetFactory : StatusBarWidgetFactory {
4534
// Mark this widget as configurable so users can enable/disable it
4635
override fun isConfigurable(): Boolean = true
4736

48-
// isEnabledByDefault checks the experimental settings for each project
49-
override fun isEnabledByDefault(): Boolean {
50-
// Since this is called without a project context, return false
51-
// The actual availability is determined by isAvailable(project)
52-
return false
53-
}
54-
55-
private fun setupSettingsListener() {
56-
val messageBus = ApplicationManager.getApplication().messageBus
57-
messageBusConnection = messageBus.connect()
58-
messageBusConnection?.subscribe(
59-
ElixirExperimentalSettings.SETTINGS_CHANGED_TOPIC,
60-
object : ElixirExperimentalSettingsListener {
61-
override fun settingsChanged(oldState: ElixirExperimentalSettings.State, newState: ElixirExperimentalSettings.State) {
62-
LOG.debug("Settings changed: statusBarWidget ${oldState.enableStatusBarWidget} -> ${newState.enableStatusBarWidget}")
63-
if (oldState.enableStatusBarWidget != newState.enableStatusBarWidget) {
64-
LOG.debug("Status bar widget setting changed, updating widget visibility")
65-
updateWidgetVisibility()
66-
}
67-
}
68-
}
69-
)
70-
}
71-
72-
private fun updateWidgetVisibility() {
73-
ApplicationManager.getApplication().invokeLater {
74-
for (project in ProjectManager.getInstance().openProjects) {
75-
if (!project.isDisposed) {
76-
updateProjectWidget(project)
77-
}
78-
}
79-
}
80-
}
81-
82-
private fun updateProjectWidget(project: Project) {
83-
project.getService(StatusBarWidgetsManager::class.java)?.updateWidget(this)
84-
}
37+
// if the experimental setting is enabled, make it so the widget immediately appears in the status bar
38+
// this was previously set to false, which required the user to enable it in project settings, and then enable
39+
// it again on the status bar.
40+
override fun isEnabledByDefault(): Boolean = true
8541
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.elixir_lang.status_bar_widget
2+
3+
import com.intellij.openapi.application.ApplicationManager
4+
import com.intellij.openapi.diagnostic.logger
5+
import com.intellij.openapi.project.DumbAware
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.startup.ProjectActivity
8+
import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager
9+
import org.elixir_lang.settings.ElixirExperimentalSettings
10+
import org.elixir_lang.settings.ElixirExperimentalSettingsListener
11+
12+
private val LOG = logger<ElixirSdkStatusWidgetStartupActivity>()
13+
14+
class ElixirSdkStatusWidgetStartupActivity : ProjectActivity, DumbAware {
15+
override suspend fun execute(project: Project) {
16+
LOG.warn("Executing startup activity for project: ${project.name}")
17+
18+
// Initial trigger to show widget if setting is already enabled
19+
refreshWidgetVisibility(project)
20+
21+
// Listen for future setting changes
22+
val connection = project.messageBus.connect()
23+
connection.subscribe(
24+
ElixirExperimentalSettings.SETTINGS_CHANGED_TOPIC,
25+
object : ElixirExperimentalSettingsListener {
26+
override fun settingsChanged(oldState: ElixirExperimentalSettings.State, newState: ElixirExperimentalSettings.State) {
27+
if (oldState.enableStatusBarWidget != newState.enableStatusBarWidget) {
28+
LOG.debug("Setting changed in ${project.name}, refreshing widget")
29+
refreshWidgetVisibility(project)
30+
}
31+
}
32+
}
33+
)
34+
}
35+
36+
private fun refreshWidgetVisibility(project: Project) {
37+
// We use invokeLater to ensure the StatusBar is fully initialized in the UI
38+
// before we ask the manager to update the widget.
39+
ApplicationManager.getApplication().invokeLater {
40+
if (!project.isDisposed) {
41+
LOG.warn("Requesting StatusBarWidgetsManager update for ${project.name}")
42+
@Suppress("IncorrectServiceRetrieving")
43+
val manager = project.getService(StatusBarWidgetsManager::class.java)
44+
manager?.updateWidget(ElixirSdkStatusWidgetFactory::class.java)
45+
}
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)