Skip to content

Commit ca94739

Browse files
committed
strategy pattern for linuxAutoLaunch, fix comments
Signed-off-by: Andrew Bernal <[email protected]>
1 parent ac1a6b7 commit ca94739

File tree

2 files changed

+59
-58
lines changed

2 files changed

+59
-58
lines changed

app/utils/autostartManager.js

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,57 @@ class AutostartManager {
1515
this.app = app
1616
this.settings = settings
1717
this.flatpakPortalManager = new FlatpakPortalManager()
18-
}
1918

20-
async setAutostartEnabled (value) {
21-
log.info(`Stretchly: setting autostart to ${value} on ${this.platform}${this.platform === 'win32' && this.windowsStore ? ' (Windows Store)' : ''}${insideFlatpak() && this.platform === 'linux' ? ' (Flatpak)' : ''}`)
22-
if (this.platform === 'linux' && insideFlatpak()) {
23-
try {
24-
// Initialize portal manager first
25-
await this.flatpakPortalManager.initialize()
26-
27-
const result = await this.flatpakPortalManager.setAutostart(value)
19+
// Decide the Linux autostart strategy once during construction
20+
if (this.platform === 'linux') {
21+
if (insideFlatpak()) {
22+
this._linuxAutoLaunch = this._createFlatpakAutostarter()
23+
} else {
24+
this._linuxAutoLaunch = new AutoLaunch({ name: 'stretchly' })
25+
}
26+
}
27+
}
2828

29-
// Only save to settings if portal call succeeded
30-
if (result) {
31-
this.settings.set('flatpakAutostart', value)
32-
log.info(`Stretchly: Saved flatpakAutostart=${value} to settings after successful portal call`)
33-
} else {
34-
log.warn('Stretchly: Portal call returned false, not saving flatpakAutostart setting')
29+
_createFlatpakAutostarter () {
30+
return {
31+
enable: async () => {
32+
try {
33+
await this.flatpakPortalManager.initialize()
34+
await this.flatpakPortalManager.setAutostart(true)
35+
this.settings.set('flatpakAutostart', true)
36+
} catch (error) {
37+
log.error('Stretchly: Failed to set autostart (enable) via XDG Portal', error)
3538
}
36-
} catch (error) {
37-
log.error('Stretchly: Failed to set autostart via XDG Portal. No fallback available for Flatpak.', error)
39+
},
40+
disable: async () => {
41+
try {
42+
await this.flatpakPortalManager.initialize()
43+
await this.flatpakPortalManager.setAutostart(false)
44+
this.settings.set('flatpakAutostart', false)
45+
} catch (error) {
46+
log.error('Stretchly: Failed to set autostart (disable) via XDG Portal', error)
47+
}
48+
},
49+
isEnabled: async () => {
50+
// XDG portals don't provide a reliable query method, so we read from our cache
51+
return Promise.resolve(this.settings.get('flatpakAutostart', false))
3852
}
39-
} else if (this.platform === 'linux') {
40-
value ? this._linuxAutoLaunch.enable() : this._linuxAutoLaunch.disable()
53+
}
54+
}
55+
56+
async setAutostartEnabled (value) {
57+
log.info(`Stretchly: setting autostart to ${value} on ${this.platform}${this.platform === 'win32' && this.windowsStore ? ' (Windows Store)' : ''}${insideFlatpak() && this.platform === 'linux' ? ' (Flatpak)' : ''}`)
58+
if (this.platform === 'linux') {
59+
await (value ? this._linuxAutoLaunch.enable() : this._linuxAutoLaunch.disable())
4160
} else if (this.platform === 'win32' && this.windowsStore) {
42-
value ? this._windowsStoreAutoLaunch.enable() : this._windowsStoreAutoLaunch.disable()
61+
await (value ? this._windowsStoreAutoLaunch.enable() : this._windowsStoreAutoLaunch.disable())
4362
} else {
4463
this.app.setLoginItemSettings({ openAtLogin: value })
4564
}
4665
}
4766

4867
async autoLaunchStatus () {
49-
if (this.platform === 'linux' && insideFlatpak()) {
50-
return this.settings.get('flatpakAutostart', false)
51-
} else if (this.platform === 'linux') {
68+
if (this.platform === 'linux') {
5269
return await this._linuxAutoLaunch.isEnabled()
5370
} else if (this.platform === 'win32' && this.windowsStore) {
5471
return await this._windowsStoreAutoLaunch.isEnabled()
@@ -57,13 +74,6 @@ class AutostartManager {
5774
}
5875
}
5976

60-
get _linuxAutoLaunch () {
61-
const stretchlyAutoLaunch = new AutoLaunch({
62-
name: 'stretchly'
63-
})
64-
return stretchlyAutoLaunch
65-
}
66-
6777
get _windowsStoreAutoLaunch () {
6878
const stretchlyAutoLaunch = new AutoLaunch({
6979
name: 'Stretchly',

app/utils/flatpakPortalManager.js

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ class FlatpakPortalManager {
1313
async initialize () {
1414
if (this.initialized) return
1515

16-
// Clean up any stale connection first
1716
if (this.bus) {
1817
try {
1918
this.bus.disconnect()
2019
} catch (err) {
21-
// Ignore errors disconnecting stale connection
20+
// Ignore disconnect errors
2221
}
2322
this.bus = null
2423
this.portal = null
@@ -45,13 +44,10 @@ class FlatpakPortalManager {
4544
* @returns {Promise<boolean>} - True if the autostart status was successfully set.
4645
*/
4746
async setAutostart (enabled) {
48-
// Ensure initialized (safe to call multiple times)
4947
await this.initialize()
5048

5149
try {
5250
const background = this.portal.getInterface('org.freedesktop.portal.Background')
53-
54-
// Create a unique handle token for this request
5551
const handleToken = `stretchly_autostart_${Date.now()}_${Math.random().toString(36).substring(7)}`
5652

5753
const options = {
@@ -61,79 +57,74 @@ class FlatpakPortalManager {
6157
'dbus-activatable': new Variant('b', false)
6258
}
6359

64-
// When DISABLING, the portal doesn't create a persistent request object
65-
// It's a fire-and-forget operation - no Response signal to wait for
60+
// When disabling autostart, the portal doesn't create a persistent request object.
61+
// No Response signal is emitted, so we can return immediately.
6662
if (!enabled) {
6763
await background.RequestBackground('', options)
68-
log.info('Stretchly: Autostart disabled via XDG Portal (no response expected).')
64+
log.info('Stretchly: Autostart disabled via XDG Portal')
6965
return true
7066
}
7167

72-
// When ENABLING, we must wait for the Response signal
68+
// When enabling autostart, we must wait for the Response signal
7369
return new Promise((resolve) => {
74-
const timeoutMs = 30000 // 30 second timeout
70+
const timeoutMs = 30000
7571
let timeoutId = null
76-
let messageListener = null // Store the listener function here
72+
let messageListener = null
7773

7874
const cleanup = () => {
7975
if (timeoutId) {
8076
clearTimeout(timeoutId)
8177
timeoutId = null
8278
}
8379
if (messageListener && this.bus) {
84-
// The actual listener removal
8580
this.bus.off('message', messageListener)
8681
messageListener = null
8782
}
8883
}
8984

90-
// Define the listener function
9185
messageListener = (msg) => {
92-
// Check if this message is the one we're waiting for
9386
if (msg.interface === 'org.freedesktop.portal.Request' &&
9487
msg.member === 'Response' &&
9588
msg.path.includes(handleToken)) {
9689
const [response, results] = msg.body
9790

98-
cleanup() // Clean up immediately (removes listener + timeout)
91+
cleanup()
9992

10093
log.info(`Stretchly: Portal Response signal received - response: ${response}, results:`, results)
10194

102-
if (response === 0) { // Success
95+
// Response codes: 0 = success, 1 = user cancelled, 2 = other error
96+
if (response === 0) {
10397
const autostartGranted = results && results.autostart && results.autostart.value === enabled
10498
if (autostartGranted) {
105-
log.info('Stretchly: Autostart successfully enabled via XDG Portal.')
99+
log.info('Stretchly: Autostart enabled via XDG Portal')
106100
} else {
107-
log.warn('Stretchly: Autostart status did not match request. Results:', results)
101+
log.warn('Stretchly: Autostart status did not match request', results)
108102
}
109103
resolve(autostartGranted)
110-
} else if (response === 1) { // User cancelled
111-
log.warn('Stretchly: User cancelled the portal request.')
104+
} else if (response === 1) {
105+
log.warn('Stretchly: User cancelled the portal request')
112106
resolve(false)
113-
} else { // Other error
107+
} else {
114108
log.error(`Stretchly: Portal request failed with response code: ${response}`)
115109
resolve(false)
116110
}
117111
}
118112
}
119113

120-
// Set the timeout
121114
timeoutId = setTimeout(() => {
122-
cleanup() // This will now remove the listener
115+
cleanup()
123116
log.error('Stretchly: Portal request timeout after 30 seconds')
124117
resolve(false)
125118
}, timeoutMs)
126119

127-
// Listen for Response signals
128-
this.bus.on('message', messageListener) // Register the named listener
120+
this.bus.on('message', messageListener)
129121

130-
// NOW make the request
131122
background.RequestBackground('', options)
132123
.then(requestPath => {
133-
log.info(`Stretchly: RequestBackground called for autostart=true, request path: ${requestPath}`)
124+
log.info(`Stretchly: RequestBackground called, request path: ${requestPath}`)
134125
})
135126
.catch(err => {
136-
cleanup() // This will now remove the listener
127+
cleanup()
137128
log.error('Stretchly: Failed to call RequestBackground:', err)
138129
resolve(false)
139130
})

0 commit comments

Comments
 (0)