The settings panel is a full-screen overlay that floats above the player. It provides access to display configuration, account actions, and a hidden server management panel for switching between backend profiles.
Opening and closing the settings screen
Settings can be opened from both the MainScreen overlay and the PlayerScreen. MainScene listens to the openSettings field on both screens:
sub OnOpenSettings()
' ...
GTV_Log("MainScene", "Opening SettingsScreen")
m.settingsReturnToOverlay = (m.isOverlayActive = true and m.mainScreen <> invalid)
settings = m.top.CreateChild("SettingsScreen")
settings.observeField("logoutRequested", "OnSettingsLogout")
settings.observeField("closeSettings", "OnSettingsClose")
settings.observeField("safeAreaChanged", "OnSettingsSafeAreaChanged")
settings.observeField("refreshChannelsRequested", "OnSettingsRefreshChannelsRequested")
settings.observeField("applyServerRequested", "OnSettingsApplyServerRequested")
settings.SetFocus(true)
m.settingsScreen = settings
end sub
When closed, MainScene restores focus to the overlay or the player depending on how settings was opened.
Safe area
The safe area margin compensates for TV overscan — some televisions crop the edges of the image. The setting is stored as a percentage (uiSafeMarginPct) and applied as an inset on all four sides of the design canvas.
- Range: 0 % to 10 % (
UI_SAFE_MARGIN_MIN_PCT / UI_SAFE_MARGIN_MAX_PCT in AppConstants.brs)
- Default: 0 %
- Adjustment: Left/Right arrow keys on the focused safe area row; each press moves by 1 %.
- Persistence: Written to the Roku Registry under the key
uiSafeMarginPct (REG_KEY_SAFE_MARGIN).
sub AdjustSafeArea(delta as Integer)
c = AppConstants()
nextPct = m.safeMarginPct + delta
if nextPct < c.UI_SAFE_MARGIN_MIN_PCT then nextPct = c.UI_SAFE_MARGIN_MAX_PCT
if nextPct > c.UI_SAFE_MARGIN_MAX_PCT then nextPct = c.UI_SAFE_MARGIN_MIN_PCT
if nextPct = m.safeMarginPct then return
m.safeMarginPct = nextPct
GTV_RegSaveSafeMarginPct(nextPct)
m.statusMessage = "Área segura actualizada a " + nextPct.ToStr() + "%"
ApplyResponsiveLayout()
m.top.safeAreaChanged = m.top.safeAreaChanged + 1
RebuildMenu()
end sub
When safeAreaChanged fires, MainScene calls ApplySceneLayout() and re-layouts all active screens immediately.
Available actions
Channel refresh
Selecting Actualizar canales emits refreshChannelsRequested to MainScene, which re-runs the playlist task in "refreshCatalog" context. The channel list is re-downloaded and the player is updated to the refreshed channel at the same index (or by matching contentId if available). The settings panel is closed before the refresh starts.
Logout
Selecting Cerrar sesión emits logoutRequested, which triggers OnLogoutRequested() in MainScene:
sub OnLogoutRequested()
GTV_Log("MainScene", "Logout requested")
ResetSessionStateAndShowLogin("", true)
end sub
This stops the player, clears saved credentials from the Roku Registry, clears the channel list and auth state from m.global, and navigates back to the login screen.
Main menu items
The settings menu is built dynamically by BuildMenuItems() in SettingsScreen.brs. In the default main mode the menu contains:
| Item | Key (kind) | Description |
|---|
| Área segura: N% | safeArea | Adjust the UI safe margin with arrow keys |
| Actualizar canales | refreshChannels | Re-download the channel playlist |
| Cerrar sesión | logout | Log out and clear credentials |
| Acerca de GlobalTV | about | Shows app version and support contact |
| Ver servidores | viewServers | Visible only after unlocking server admin mode |
| Cerrar | close | Close the panel and return to the player |
Server management panel
The server panel is hidden by default. It is unlocked by pressing OK on the Acerca de GlobalTV item five times (SERVER_ADMIN_UNLOCK_TAPS = 5). Once unlocked, a Ver servidores item appears in the main menu.
Server modes
The settings screen has three internal modes:
| Mode | Constant | Purpose |
|---|
| Main | MODE_MAIN | Default settings menu |
| Servers | MODE_SERVERS | List of all server profiles |
| Actions | MODE_ACTIONS | Per-server actions (apply, test, edit, delete) |
Default server profiles
The default profiles are defined in source/utils/ServerManager.brs:
function GTV_DefaultServerProfiles() as Object
return [
{
id: "local_default"
name: "Local"
baseUrl: "http://172.17.11.2:3333"
type: "lan"
builtIn: true
enabled: true
}
{
id: "public_default"
name: "Publico"
baseUrl: "https://admin.globaltv.lat"
type: "wan"
builtIn: true
enabled: true
}
]
end function
These correspond to the two entries in SERVER_LIST in AppConstants.brs. The "Local" profile is a LAN server on 172.17.11.2:3333; the "Publico" profile is the WAN endpoint at admin.globaltv.lat.
Applying a server
Selecting Aplicar ahora on a server profile emits applyServerRequested to MainScene, which calls ApplyServerNow(). This:
- Saves the new server URL to the Registry under
lastServer.
- Updates
m.global.activeServer.
- Stops the current video stream.
- Clears auth and catalog state.
- Restarts the handshake flow against the new server, followed by auto-login and playlist load.
Testing a server
Selecting Probar conexión launches a ServerProbeTask that calls GTV_PingServer() against the selected server’s /health endpoint and reports the result as a status message in the detail panel — without affecting the active session.
ServerManager: LAN vs WAN selection logic
When the app needs to find a reachable server (e.g., during handshake), GTV_ServerBuildAutoProbeList() builds an ordered probe sequence that always tries LAN servers before WAN servers:
function GTV_ServerBuildAutoProbeList() as Object
profiles = GTV_LoadServerProfiles()
lan = []
wan = []
for each profile in profiles
if profile.type <> invalid and profile.type = "lan"
lan.Push(profile.baseUrl)
else
wan.Push(profile.baseUrl)
end if
end for
order = []
passes = AppConstants().SERVER_LAN_FORCE_RETRIES
if passes < 1 then passes = 1
if lan.Count() > 0
for i = 0 to passes - 1
for each baseUrl in lan
order.Push(baseUrl)
end for
end for
end if
if wan.Count() > 0
for each baseUrl in wan
order.Push(baseUrl)
end for
end if
return order
end function
SERVER_LAN_FORCE_RETRIES = 3
LAN servers appear in the probe list SERVER_LAN_FORCE_RETRIES times (default 3) before WAN servers are tried once. With the default profiles the probe order is:
1. http://172.17.11.2:3333 (LAN attempt 1)
2. http://172.17.11.2:3333 (LAN attempt 2)
3. http://172.17.11.2:3333 (LAN attempt 3)
4. https://admin.globaltv.lat (WAN)
This gives the LAN server three chances to respond before the app falls back to the public WAN endpoint — useful when the LAN server is temporarily slow or takes a moment to wake up.
Type inference (GTV_ServerInferType()) classifies any URL matching 172.17.*, 192.168.*, 10.*, or localhost as "lan". Everything else is classified as "wan".
Registry persistence
Settings data is written to the Roku Registry under the "GlobalTV" section (REG_SECTION):
| Registry key | Constant | What is stored |
|---|
lastServer | REG_KEY_SERVER | Base URL of the last successfully used server |
serverProfiles | REG_KEY_SERVER_PROFILES | Full JSON array of server profile objects |
uiSafeMarginPct | REG_KEY_SAFE_MARGIN | Safe area margin percentage (integer, 0–10) |
Server profiles are serialised with FormatJson() and deserialised with ParseJson() + GTV_SanitizeServerProfiles(), which validates and deduplicates each profile on load.
Deleting all server profiles from the panel is blocked — GTV_ServerCanDelete() returns false when only one profile remains. At least one server must always be present.