Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ ELYTerminal. A terminal on GPUI and Ely components. `PRD.md` says what it does;
- 2026-10-14: Appearance shows every built-in theme as Ely's `RadioCard` in a `SimpleGrid`, each over a small window in the theme's colors. Separate dark theme copies the theme into `dark_theme`, so turning it on changes nothing until a dark card is picked. A theme change re-dresses the chrome at once. Font family comes from Ely's `FontPicker`; size, line height and padding from its `NumberInput`, which saves a number on Enter, on leaving the field and on each step. A font saves, and a settings file starts, only when gpui loads it as the terminal draws it: gpui falls back to another font without a word and loads none without an `m`, so the terminal draws with no font but its own. The cursor preview is a prompt in the terminal's font and theme, its cursor drawn as the terminal draws it, blinking on the terminal's beat. Opacity moves by whole percents, so the saved fraction carries no float noise. A change the store refuses leaves the setting as it was, and the page says why at its top; a number field drops its draft, and the font picker shows the saved family again. The settings window opens at 900 by 640, room for three theme columns.
- 2026-10-14: Terminal shows the shell and where sessions start, which a General page held until the owner dropped it, then scrollback lines, Option as Alt, on macOS only, since elsewhere Alt is Alt, copy on select, the sessions column's drag and right press, and Ely, then every shortcut in Ely's `KeyboardShortcutsList`, read from the keymap: the bindings of each listed command that apply in the main window's terminal, matched at any depth of its context stack as gpui matches them, so the list cannot drift from the keys. The engine reads each when it needs it, so a change applies at once to every session; a smaller scrollback drops the history past it.
- 2026-10-14: the main window lets the desktop through while Background opacity is under 1, blurred or clear as Background blur says, through gpui's `Blurred` (macOS's NSVisualEffectView, Windows' acrylic) or `Transparent`; at 1 it is `Opaque`. The workspace sets it as the settings change. Ely's `ColumnShell::glass`, added to Ely for this, grounds the columns in the palette's glass, which the opacity sets, so the title bar and every column let the desktop through alike; the palette's `bg` stays solid, so a dialog, the Git diff among them, hides what lies under it. The terminal paints no ground over the glass, or the two would stack; a program's own background (OSC 11) paints over it. Ely's own themes pass their palette too, Ely's colors with the glass set. The settings window stays opaque.
- 2026-11-03: Background image paints where Picture scope says: the terminal's column or the window below the title bar, never the title bar. `src/workspace/wallpaper.rs` paints the window's ground, the theme's background at the background opacity, and the picture over it at that opacity, once behind the workspace; a canvas ruler in the terminal column's body records those bounds, since a column's header may hold it wider than its width setting, and asks for another frame when they move. While a picture is set the columns' glass is 0, so the picture keeps its colors and the columns stand transparent over the ground; a program's own background (OSC 11) still paints over it.
- 2026-11-03: the picture's size, position and repeat are CSS's, kept as strings and read by `src/settings/picture.rs`: `PictureSize` (cover, contain, fill, auto, or a width and a height), `PictureLength` (auto, pixels, a percentage of 0 to 100), `PicturePosition` with a `PictureAxis` for each side, and `PictureRepeat` (no repeat, across, down, both). A size of `51%` prints `51% auto`, its height kept as written; a place of `right top` prints as written. `src/workspace/wallpaper.rs` sizes the picture against the image's own pixels at the window's scale, places it, and tiles it from before its box, at most 400 tiles, and a picture past that draws once and logs. The rows sit in Settings › Appearance › Background, after Picture scope; a size or a place that does not read says why under its field.
- 2026-10-15: on Wayland the window asks for `ext_background_effect_v1` beside gpui's `org_kde_kwin_blur`. A guest connection on gpui's own display binds it, takes the effect for the window's surface once, and blurs the window's pane: the surface less Ely's resize margin on each free edge of a client-drawn window, worked out each frame and sent only when it changes; it goes and comes back with Blurred and lands at the surface's next commit, which every frame makes. The guest connection reads the display only while the window opens, before gpui's loop runs, and is never dropped: a drop destroys its proxies through the display, which gpui may close first. The log names what the compositor offers, so which way blur goes: `ext_background_effect_v1`, gpui's `org_kde_kwin_blur`, or none, the desktop clear. Its test runs a `wayland-server` compositor on a socket pair.
- 2026-10-15: on a client-drawn window, so on Linux, Ely's `ResizeBorder` paints its pane solid and shadowed under the content, which kept the desktop from showing at all. `ResizeBorder::glass`, added to Ely for this, leaves the pane to the content while the window is see-through: no ground, nor the shadow gpui draws under the box, which would tint it. So the blur covers the pane alone and the resize margin stays clear. On X11 the window names its pane in `_KDE_NET_WM_BLUR_BEHIND_REGION` (CARDINAL, 32: x, y, width, height in the window's pixels), as Ghostty names its own, and drops the property when Blurred goes; KWin reads it, other compositors pass it by. It goes over a connection of ELYTerminal's own to `$DISPLAY`, which gpui opens too: a property belongs to the window, whoever sets it. gpui's own `org_kde_kwin_blur` on KDE's Wayland still covers the whole surface, margin included, beyond ELYTerminal's reach.
- 2026-10-15: the macOS menu bar is the PRD's: ELYTerminal (Settings…, Quit), Shell (New Session, Close Session), Edit (Copy, Paste, Select All, Find), View (Toggle Sessions, Toggle Right Panel, Bigger, Smaller, Reset Size), Window (Minimize, Zoom, then the windows macOS lists). An item shows the key bound to its action, so the menus are set after the bindings; Copy, Paste and Select All go through AppKit's `copy:`, `paste:` and `selectAll:`, as gpui's `OsAction` maps them. They are Ely's text input actions, which `forms` exports for this, and the terminal handles them too: gpui sends a menu's action to what holds focus and enables the item only where a handler waits, so one action serves the terminal, find and every field. The new keys are Ghostty's: Cmd-Q, Cmd-A, Cmd-= and Cmd-+, Cmd-minus, Cmd-0, Cmd-M. Off macOS Quit and Select All take Ctrl-Shift, since Ctrl with a letter types a control byte; the font's size takes plain Ctrl with =, +, minus and 0, which type none, as in Ghostty, Alacritty and Windows Terminal; Minimize has no key there. Bigger and Smaller move every session's font a point, inside the Size range, and Reset Size goes back to the setting; nothing saves the change, as in Ghostty. Select All runs from the first character in the history to the last on the screen, the blanks around them left out, as Ghostty's, though a space under a combining mark shows a character and counts as one; copy on select takes it, and a blank grid selects nothing.
Expand Down
2 changes: 1 addition & 1 deletion PRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Cmd-, opens it; on Windows and Linux, which have no menu bar, so does a gear in
- Separate dark theme: a switch; when on, a second grid for dark mode.
- Font family: a list of installed fonts. Fallbacks: installed families tried in order for a character the family lacks, each added, changed or removed in a list of pickers. CJK font: a family Chinese, Japanese and Korean characters draw in, with their marks and variation selectors, before Family, empty by default, cleared by Clear. Font size. Weight, 100 to 900, 400 by default, normal text's; bold sits 300 above it, up to 900. Line height. Ligatures. Antialiasing, on Windows and Linux: Grayscale, as Windows Terminal draws, by default, or Subpixel, which gpui draws only on an opaque window.
- Cursor: style (block, bar, underline, hollow), blink, glide, on by default, which slides the cursor to its new cell in 90 ms, with a live preview.
- Background opacity: a slider. Background image: a picture under the terminal, at that opacity, chosen as a file. Background blur: a switch. Backdrop, on Windows 11 from build 22621: Acrylic, Mica or Mica Alt.
- Background opacity: a slider. Background image: a picture under the terminal or the window, at that opacity, chosen as a file. Picture scope: the terminal's column, or the window below the title bar. Picture size: cover, contain, fill, auto, or a width and a height such as `51% auto`. Picture position: a place such as `right top` or `125% 100%`. Picture repeat: no repeat, across, down or both. Background blur: a switch. Backdrop, on Windows 11 from build 22621: Acrylic, Mica or Mica Alt.
- Padding: horizontal and vertical.
- Terminal
- Shell: a path; empty runs the login shell, on Windows `pwsh`, else `powershell`, else `cmd`. On Windows a session takes the registry's environment as it starts.
Expand Down
1 change: 1 addition & 0 deletions docs/en_us/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ English / [中文](../zh_cn/features.md)
- Interface font and size in Settings › Appearance: any installed family, with a sample line, and 12 to 16 px for every window's chrome; the terminal keeps its own font.
- On Windows, Settings › Terminal › Explorer menu adds Open in ELYTerminal to a folder's right-click menu, for you alone, and removes it; on Windows 11 it sits under Show more options. `elyterminal FOLDER` starts the first session in FOLDER on every system; cmd, which refuses a network share as its folder, says so and starts in the Windows folder. The folder may also follow `--working-directory`, `-d` or `--startingDirectory`, as xdg-terminal-exec and Windows Terminal pass it.
- Background opacity and blur: NSVisualEffectView on macOS, acrylic on Windows, or on Windows 11 from build 22621 Mica or Mica Alt, as Settings › Appearance › Backdrop says, `ext_background_effect_v1` or `org_kde_kwin_blur` on Wayland, `_KDE_NET_WM_BLUR_BEHIND_REGION` on X11, which KWin reads. Blur shows only while the opacity is under 100%. Hyprland blurs only while its own `decoration:blur:enabled` is on, and Omarchy 4.0.4 turns it off; to turn it on there, add `hl.config({ decoration = { blur = { enabled = true } } })` to `~/.config/hypr/looknfeel.lua`.
- Background image: a picture at Settings › Appearance › Background image, drawn at the background's opacity where Picture scope says, under the terminal's column or under the whole window below the title bar. A column's header can hold the terminal wider than its width setting, and the picture follows the terminal itself. The picture keeps its colors: while one is set, the columns' glass is 0, so a window-wide picture shows through them. Its size, position and repeat are CSS's: `cover`, `contain`, `fill`, `auto` or a width and a height such as `51% auto`; a place such as `right top` or `125% 100%`; and no repeat, repeat across, down or both.
1 change: 1 addition & 0 deletions docs/zh_cn/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
- 设置 › 外观 中的界面字体和字号:任一已安装字体,附示例行,12 到 16 px,作用于每个窗口的界面;终端保留自己的字体。
- Windows 上,设置 › 终端 › 资源管理器菜单 可为当前用户在文件夹的右键菜单中加入或移除“在 ELYTerminal 中打开”;Windows 11 中它位于“显示更多选项”下。`elyterminal FOLDER` 在各系统上都让第一个会话从 FOLDER 开始;cmd 不接受网络共享作为当前目录,会自行提示并进入 Windows 目录。文件夹也可以写在 `--working-directory`、`-d` 或 `--startingDirectory` 之后,与 xdg-terminal-exec 和 Windows Terminal 的写法相同。
- 背景不透明度和模糊:macOS 上是 NSVisualEffectView,Windows 上是 acrylic,Windows 11 build 22621 起可按设置 › 外观 › 背景材质选云母或云母 Alt,Wayland 上是 `ext_background_effect_v1` 或 `org_kde_kwin_blur`,X11 上是 `_KDE_NET_WM_BLUR_BEHIND_REGION`,KWin 会读它。模糊只在不透明度低于 100% 时出现。Hyprland 只在自己的 `decoration:blur:enabled` 打开时模糊,而 Omarchy 4.0.4 把它关掉了;要在那里打开,把 `hl.config({ decoration = { blur = { enabled = true } } })` 加到 `~/.config/hypr/looknfeel.lua`。
- 背景图片:在设置 › 外观 › 背景图片 选一张图,按背景不透明度显示,位置由 图片范围 决定:终端列下方,或标题栏以下的整个窗口。列头可能让终端比宽度设置更宽,图片跟着终端本身。图片保持原色:设置图片时各列的玻璃为 0,整窗图片会从列中透出。尺寸、位置和重复与 CSS 相同:`cover`、`contain`、`fill`、`auto`,或宽高如 `51% auto`;位置如 `right top` 或 `125% 100%`;重复可选不重复、横向、纵向或两者。
1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub fn start(cx: &mut App) -> anyhow::Result<()> {
theme,
settings.custom_themes.clone(),
settings.background_opacity,
!settings.background_image.is_empty(),
)
};
let mut image = SettingsStore::get(cx).background_image.clone();
Expand Down
20 changes: 19 additions & 1 deletion src/i18n/en.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,26 @@ pub const MESSAGES: &[(&str, &str)] = &[
("et.appearance.image", "Background image"),
(
"et.appearance.image_hint",
"A picture under the terminal, at the background's opacity",
"A picture under the terminal or the window, at the background's opacity",
),
("et.appearance.scope", "Picture scope"),
("et.appearance.scope_terminal", "Terminal"),
("et.appearance.scope_window", "Window"),
("et.appearance.picture_size", "Picture size"),
(
"et.appearance.picture_size_hint",
"Cover, contain, fill, auto, or a width and a height: a percentage, pixels or auto",
),
("et.appearance.picture_position", "Picture position"),
(
"et.appearance.picture_position_hint",
"Where it sits: a side such as right top, or an offset such as 125% 100%",
),
("et.appearance.picture_repeat", "Picture repeat"),
("et.appearance.picture_repeat_no_repeat", "No repeat"),
("et.appearance.picture_repeat_repeat", "Repeat"),
("et.appearance.picture_repeat_x", "Repeat across"),
("et.appearance.picture_repeat_y", "Repeat down"),
("et.custom.new", "New theme"),
("et.custom.name_of", "Custom {number}"),
("et.custom.name", "Name"),
Expand Down
20 changes: 19 additions & 1 deletion src/i18n/zh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,26 @@ pub const MESSAGES: &[(&str, &str)] = &[
("et.appearance.image", "背景图片"),
(
"et.appearance.image_hint",
"终端下方的图片,按背景不透明度显示",
"终端或窗口下方的图片,按背景不透明度显示",
),
("et.appearance.scope", "图片范围"),
("et.appearance.scope_terminal", "终端"),
("et.appearance.scope_window", "窗口"),
("et.appearance.picture_size", "图片尺寸"),
(
"et.appearance.picture_size_hint",
"cover、contain、fill、auto,或宽度与高度:百分比、像素或 auto",
),
("et.appearance.picture_position", "图片位置"),
(
"et.appearance.picture_position_hint",
"图片所在:right top 这样的边,或 125% 100% 这样的偏移",
),
("et.appearance.picture_repeat", "图片重复"),
("et.appearance.picture_repeat_no_repeat", "不重复"),
("et.appearance.picture_repeat_repeat", "重复"),
("et.appearance.picture_repeat_x", "横向重复"),
("et.appearance.picture_repeat_y", "纵向重复"),
("et.custom.new", "新建主题"),
("et.custom.name_of", "自定义 {number}"),
("et.custom.name", "名称"),
Expand Down
23 changes: 23 additions & 0 deletions src/settings/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod picture;
mod profiles;
mod store;
pub mod window;
Expand All @@ -14,6 +15,7 @@ use serde::{Deserialize, Serialize};

use crate::themes;

pub use picture::{PictureAxis, PictureLength, PicturePosition, PictureRepeat, PictureSize};
pub use profiles::{Profile, command_line, words};
pub use store::{SettingsStore, load, save};

Expand Down Expand Up @@ -95,6 +97,15 @@ pub enum PanelTab {
Files,
}

/// Where the background picture paints: the terminal's column or the window below the title bar.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BackgroundScope {
#[default]
Terminal,
Window,
}

/// Everything the settings window edits. A field the file leaves out takes its default.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default, deny_unknown_fields)]
Expand All @@ -118,6 +129,14 @@ pub struct Settings {
pub custom_themes: Vec<themes::CustomTheme>,
/// A picture under the terminal; empty for none.
pub background_image: String,
/// Where the picture paints: the terminal's column or the window below the title bar.
pub background_scope: BackgroundScope,
/// How the picture fills its box, as CSS's `background-size`.
pub background_size: PictureSize,
/// Where the picture sits in its box, as CSS's `background-position`.
pub background_position: PicturePosition,
/// Whether the picture tiles to fill its box.
pub background_repeat: PictureRepeat,
pub font_family: String,
/// Families tried in order for a character Font family lacks.
pub font_fallbacks: Vec<String>,
Expand Down Expand Up @@ -193,6 +212,10 @@ impl Default for Settings {
dark_theme: None,
custom_themes: Vec::new(),
background_image: String::new(),
background_scope: BackgroundScope::Terminal,
background_size: PictureSize::Cover,
background_position: PicturePosition::default(),
background_repeat: PictureRepeat::NoRepeat,
font_family: "JetBrains Mono".into(),
font_fallbacks: Vec::new(),
cjk_font: String::new(),
Expand Down
Loading