mirror of
https://github.com/openai/codex.git
synced 2026-11-12 14:41:42 +00:00
Advertise the Desktop app in graphical Linux sessions (#39656)
## What changed - Add Linux-specific install and launch guidance to the generic and paid tooltip pools when `DISPLAY` or `WAYLAND_DISPLAY` is set. - Keep the Linux tooltip hidden in WSL and headless sessions, and preserve platform-specific macOS and Windows behavior. ## Testing - Add coverage for native graphical Linux, WSL, headless Linux, macOS, and Windows tooltip selection. GitOrigin-RevId: cbe9435db064d5718a591db363dcb7cc1429d5ee
This commit is contained in:
1 parent
1802a65571
commit
4a432d180d
2 files changed
+88
-10
No files matched your search
@@ -10,6 +10,9 @@ const IS_MACOS: bool = cfg!(target_os = "macos");
|
|||||||
const IS_WINDOWS: bool = cfg!(target_os = "windows");
|
const IS_WINDOWS: bool = cfg!(target_os = "windows");
|
||||||
|
|
||||||
const APP_TOOLTIP: &str = "Try the **Desktop app**. Run 'codex app' or visit https://chatgpt.com/codex?app-landing-page=true";
|
const APP_TOOLTIP: &str = "Try the **Desktop app**. Run 'codex app' or visit https://chatgpt.com/codex?app-landing-page=true";
|
||||||
|
const MACOS_APP_TOOLTIP: &str =
|
||||||
|
"Run `codex app` to open the Desktop app (it installs on macOS if needed).";
|
||||||
|
const LINUX_APP_TOOLTIP: &str = "Try the **Desktop app** on Linux: install it from https://learn.chatgpt.com/docs/linux/linux-app and run 'chatgpt'.";
|
||||||
const FAST_TOOLTIP: &str =
|
const FAST_TOOLTIP: &str =
|
||||||
"*New* Use **/fast** to enable our fastest inference with increased plan usage.";
|
"*New* Use **/fast** to enable our fastest inference with increased plan usage.";
|
||||||
const OTHER_TOOLTIP: &str = "*New* Build faster with the **Desktop app**. Run 'codex app' or visit https://chatgpt.com/codex?app-landing-page=true";
|
const OTHER_TOOLTIP: &str = "*New* Build faster with the **Desktop app**. Run 'codex app' or visit https://chatgpt.com/codex?app-landing-page=true";
|
||||||
@@ -23,14 +26,11 @@ lazy_static! {
|
|||||||
static ref TOOLTIPS: Vec<&'static str> = RAW_TOOLTIPS
|
static ref TOOLTIPS: Vec<&'static str> = RAW_TOOLTIPS
|
||||||
.lines()
|
.lines()
|
||||||
.map(str::trim)
|
.map(str::trim)
|
||||||
.filter(|line| {
|
.filter(|line| !line.is_empty() && !line.starts_with('#'))
|
||||||
if line.is_empty() || line.starts_with('#') {
|
.chain(if IS_MACOS {
|
||||||
return false;
|
Some(MACOS_APP_TOOLTIP)
|
||||||
}
|
} else {
|
||||||
if !IS_MACOS && !IS_WINDOWS && line.contains("codex app") {
|
linux_app_tooltip(LinuxDesktopSession::current())
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
static ref ALL_TOOLTIPS: Vec<&'static str> = {
|
static ref ALL_TOOLTIPS: Vec<&'static str> = {
|
||||||
@@ -87,11 +87,41 @@ pub(crate) fn get_tooltip(plan: Option<PlanType>, fast_mode_enabled: bool) -> Op
|
|||||||
pick_tooltip(&mut rng).map(str::to_string)
|
pick_tooltip(&mut rng).map(str::to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LinuxDesktopSession {
|
||||||
|
has_display: bool,
|
||||||
|
is_wsl: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinuxDesktopSession {
|
||||||
|
fn current() -> Self {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
has_display: std::env::var_os("DISPLAY").is_some_and(|value| !value.is_empty())
|
||||||
|
|| std::env::var_os("WAYLAND_DISPLAY").is_some_and(|value| !value.is_empty()),
|
||||||
|
is_wsl: crate::clipboard_paste::is_probably_wsl(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
has_display: false,
|
||||||
|
is_wsl: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linux_app_tooltip(session: LinuxDesktopSession) -> Option<&'static str> {
|
||||||
|
(session.has_display && !session.is_wsl).then_some(LINUX_APP_TOOLTIP)
|
||||||
|
}
|
||||||
|
|
||||||
fn paid_app_tooltip() -> Option<&'static str> {
|
fn paid_app_tooltip() -> Option<&'static str> {
|
||||||
if IS_MACOS || IS_WINDOWS {
|
if IS_MACOS || IS_WINDOWS {
|
||||||
Some(APP_TOOLTIP)
|
Some(APP_TOOLTIP)
|
||||||
} else {
|
} else {
|
||||||
None
|
linux_app_tooltip(LinuxDesktopSession::current())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +354,7 @@ pub(crate) mod announcement {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::tooltips::announcement::parse_announcement_tip_toml;
|
use crate::tooltips::announcement::parse_announcement_tip_toml;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
|
|
||||||
@@ -344,6 +375,54 @@ mod tests {
|
|||||||
assert_eq!(expected, pick_tooltip(&mut rng));
|
assert_eq!(expected, pick_tooltip(&mut rng));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn desktop_app_tooltip_uses_supported_platform_launcher() {
|
||||||
|
let tooltip = TOOLTIPS
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.find(|tip| tip.contains("Desktop app"));
|
||||||
|
|
||||||
|
if linux_app_tooltip(LinuxDesktopSession::current()).is_some() {
|
||||||
|
let tooltip = tooltip.expect("Linux should advertise the desktop app");
|
||||||
|
assert_eq!(paid_app_tooltip(), Some(tooltip));
|
||||||
|
} else if IS_MACOS {
|
||||||
|
let tooltip = tooltip.expect("macOS should advertise the desktop app");
|
||||||
|
insta::assert_snapshot!(tooltip, @"Run `codex app` to open the Desktop app (it installs on macOS if needed).");
|
||||||
|
assert_eq!(paid_app_tooltip(), Some(APP_TOOLTIP));
|
||||||
|
} else if IS_WINDOWS {
|
||||||
|
assert_eq!(tooltip, None);
|
||||||
|
assert_eq!(paid_app_tooltip(), Some(APP_TOOLTIP));
|
||||||
|
} else {
|
||||||
|
assert_eq!(tooltip, None);
|
||||||
|
assert_eq!(paid_app_tooltip(), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn linux_desktop_app_tooltip_requires_graphical_native_session() {
|
||||||
|
let tooltip = linux_app_tooltip(LinuxDesktopSession {
|
||||||
|
has_display: true,
|
||||||
|
is_wsl: false,
|
||||||
|
})
|
||||||
|
.expect("graphical native Linux should advertise the desktop app");
|
||||||
|
insta::assert_snapshot!(tooltip, @"Try the **Desktop app** on Linux: install it from https://learn.chatgpt.com/docs/linux/linux-app and run 'chatgpt'.");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
linux_app_tooltip(LinuxDesktopSession {
|
||||||
|
has_display: false,
|
||||||
|
is_wsl: false,
|
||||||
|
}),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
linux_app_tooltip(LinuxDesktopSession {
|
||||||
|
has_display: true,
|
||||||
|
is_wsl: true,
|
||||||
|
}),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn paid_tooltip_pool_rotates_between_promos() {
|
fn paid_tooltip_pool_rotates_between_promos() {
|
||||||
let mut seen = std::collections::BTreeSet::new();
|
let mut seen = std::collections::BTreeSet::new();
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ Use /fork to branch the current chat into a new thread.
|
|||||||
Use /side to start a side conversation in a temporary fork without polluting the main thread.
|
Use /side to start a side conversation in a temporary fork without polluting the main thread.
|
||||||
Use /init to create an AGENTS.md with project-specific guidance.
|
Use /init to create an AGENTS.md with project-specific guidance.
|
||||||
Use /mcp to list configured MCP tools.
|
Use /mcp to list configured MCP tools.
|
||||||
Run `codex app` to open the Desktop app (it installs on macOS if needed).
|
|
||||||
Use /personality to customize how Codex communicates.
|
Use /personality to customize how Codex communicates.
|
||||||
Use /rename to rename your threads for easier thread resuming.
|
Use /rename to rename your threads for easier thread resuming.
|
||||||
Use the OpenAI docs MCP for API questions; enable it with `codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp`.
|
Use the OpenAI docs MCP for API questions; enable it with `codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp`.
|
||||||
|
|||||||
Reference in new issue
Block a user