T65: a window property marks a move from WM_ENTERSIZEMOVE to WM_EXITSIZEMOVE, so a window blurred mid-move, which gpui gives acrylic at once, takes the clear accent again until the move ends
This commit is contained in:
3 files changed
+39
-19
No files matched your search
@@ -121,4 +121,4 @@ ELYTerminal. A terminal on GPUI and Ely components. `PRD.md` says what it does;
|
||||
- 2026-10-19: a user found the IME's candidate box jumping on Windows after 0.1.6. gpui places it, through `ImmSetCompositionWindow` and `ImmSetCandidateWindow`, only when a composition starts, at the caret the terminal reports, the grid cursor's cell from the last frame, hidden or not. On the owner's PC, WeType under powershell.exe and under a status line redrawn every 100 ms put the box at the caret in 23 compositions out of 23, so the owner closed it unreproduced. The terminal logs each caret the input method asks for, at debug, and each move of the caret, at trace, so the next report carries where the box was told to go.
|
||||
- 2026-10-19: Ely's shirt and back hair run on below the edge she holds, which a user asked for after 0.1.6, where a hop lifted her whole figure off the window and showed a gap under her collar and hands: both continue down to 340 in the icon's units, 54 below the edge at 286, past her highest lift, a hop of 31 with a press's 0.6 of one on it, so a hop shows more of her and never the gap; at rest the part below the edge lies outside her window and does not show. The shirt moves with her body, the hair with her head, as before; the hair behind her hands fills under them as she lifts.
|
||||
- 2026-10-19: a double press on a session's row renames it, which a user asked for after 0.1.6. Ely's `ListItem::editor`, added to Ely for this, draws Ely's text field in the title's place; the row's first press selects the session, as ever, and its second opens the field, holding what the session is called, selected, with the focus. Enter keeps what it holds, Escape drops it, and a blur keeps it, as Windows Terminal's tab rename does; whenever the field closes while it still holds the window's focus, the shown terminal takes it, and a press that took the focus elsewhere keeps it there. A window that goes inactive blurs the field and keeps its focus there, so a field closed by that blur, focus handed to nothing, left the terminal deaf to keys once the window came back. A press inside the open field stays the field's: the row would select its session, which takes the focus to the terminal and ends the rename. The name, its ends trimmed, stands over the program's title in the row, the terminal's header and the window's title until renamed again, a program's later titles passing under it; an empty one gives the title back to the program. It lives as long as the session, and notifications keep the program's title. Each program title, each rename and its end are logged.
|
||||
- 2026-10-19: on Windows 10 a blurred window's acrylic clears while the window moves or sizes, which a user asked for in issue #3 after 0.1.5, where dragging the window trailed the pointer by seconds: that DWM samples the acrylic again at each step of the move loop, while gpui draws through it every 10 ms, so the moves pile up; Windows 11's DWM does not, and keeps its acrylic. At start `RtlGetVersion` reads the build; below 22000 the main window's procedure is ELYTerminal's own, passing every message on to gpui's: at `WM_ENTERSIZEMOVE` a blurred window takes the accent gpui gives Transparent, a clear gradient, and at `WM_EXITSIZEMOVE` gpui's acrylic again, `SWP_FRAMECHANGED` telling DWM, both through `SetWindowCompositionAttribute` as gpui calls it. A window property marks the window blurred, set as the blur setting changes, so an opaque or clear window moves as it is. The log names which way the build goes and each switch. On Windows 11, with the build check raised, a drag by the terminal's header logged both switches and showed the glass clear mid-drag and blurred at rest; Windows 10 itself went untested, the fix following the issue's own trial.
|
||||
- 2026-10-19: on Windows 10 a blurred window's acrylic clears while the window moves or sizes, which a user asked for in issue #3 after 0.1.5, where dragging the window trailed the pointer by seconds: that DWM samples the acrylic again at each step of the move loop, while gpui draws through it every 10 ms, so the moves pile up; Windows 11's DWM does not, and keeps its acrylic. At start `RtlGetVersion` reads the build; below 22000 the main window's procedure is ELYTerminal's own, passing every message on to gpui's: at `WM_ENTERSIZEMOVE` a blurred window takes the accent gpui gives Transparent, a clear gradient, and at `WM_EXITSIZEMOVE` gpui's acrylic again, `SWP_FRAMECHANGED` telling DWM, both through `SetWindowCompositionAttribute` as gpui calls it. A window property marks the window blurred, set as the blur setting changes, so an opaque or clear window moves as it is; another marks it moving, from `WM_ENTERSIZEMOVE`, which Windows sends once, to `WM_EXITSIZEMOVE`, so a window blurred mid-move, which gpui gives acrylic at once, takes the clear accent again until the move ends. The log names which way the build goes and each switch. On Windows 11, with the build check raised, a drag by the terminal's header logged both switches and showed the glass clear mid-drag and blurred at rest; Windows 10 itself went untested, the fix following the issue's own trial.
|
||||
+37
-17
@@ -31,6 +31,8 @@ static GPUI: AtomicIsize = AtomicIsize::new(0);
|
||||
|
||||
/// A window's property while it is blurred, which its moves read.
|
||||
const BLURRED: PCWSTR = w!("ElyTerminalBlurred");
|
||||
/// A window's property while it moves or sizes, which a change of its blur reads.
|
||||
const MOVING: PCWSTR = w!("ElyTerminalMoving");
|
||||
|
||||
/// gpui's accents: acrylic for Blurred, a clear gradient for Transparent.
|
||||
const ACRYLIC: u32 = 4;
|
||||
@@ -61,14 +63,20 @@ impl Moves {
|
||||
Ok(Some(Self { window }))
|
||||
}
|
||||
|
||||
/// Notes whether the window is blurred, as its moves read it.
|
||||
/// Notes whether the window is blurred, as its moves read it; one blurred mid-move stays clear until the move ends.
|
||||
pub fn blurred(&self, on: bool) {
|
||||
if on {
|
||||
if unsafe { SetPropW(self.window, BLURRED, 1 as _) } == 0 {
|
||||
log::error!("blur: the window's blurred mark does not set");
|
||||
}
|
||||
} else {
|
||||
if !on {
|
||||
unsafe { RemovePropW(self.window, BLURRED) };
|
||||
return;
|
||||
}
|
||||
if unsafe { SetPropW(self.window, BLURRED, 1 as _) } == 0 {
|
||||
log::error!("blur: the window's blurred mark does not set");
|
||||
}
|
||||
if !unsafe { GetPropW(self.window, MOVING) }.is_null() {
|
||||
match accent(self.window, CLEAR) {
|
||||
Ok(()) => log::debug!("blur: blurred mid-move, the window moves clear"),
|
||||
Err(error) => log::error!("{error:#}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,22 +91,34 @@ unsafe extern "system" fn moving(
|
||||
let gpui: WNDPROC = unsafe { std::mem::transmute(GPUI.load(Ordering::Relaxed)) };
|
||||
let blurred = !unsafe { GetPropW(window, BLURRED) }.is_null();
|
||||
match message {
|
||||
WM_ENTERSIZEMOVE if blurred => match accent(window, CLEAR) {
|
||||
Ok(()) => log::debug!("blur: the window moves clear"),
|
||||
Err(error) => log::error!("{error:#}"),
|
||||
},
|
||||
WM_EXITSIZEMOVE if blurred => {
|
||||
match accent(window, ACRYLIC) {
|
||||
Ok(()) => log::debug!("blur: the window rests blurred again"),
|
||||
Err(error) => log::error!("{error:#}"),
|
||||
WM_ENTERSIZEMOVE => {
|
||||
if unsafe { SetPropW(window, MOVING, 1 as _) } == 0 {
|
||||
log::error!("blur: the window's moving mark does not set");
|
||||
}
|
||||
let flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED;
|
||||
if unsafe { SetWindowPos(window, std::ptr::null_mut(), 0, 0, 0, 0, flags) } == 0 {
|
||||
log::error!("blur: DWM hears of no new frame after the move");
|
||||
if blurred {
|
||||
match accent(window, CLEAR) {
|
||||
Ok(()) => log::debug!("blur: the window moves clear"),
|
||||
Err(error) => log::error!("{error:#}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
WM_EXITSIZEMOVE => {
|
||||
unsafe { RemovePropW(window, MOVING) };
|
||||
if blurred {
|
||||
match accent(window, ACRYLIC) {
|
||||
Ok(()) => log::debug!("blur: the window rests blurred again"),
|
||||
Err(error) => log::error!("{error:#}"),
|
||||
}
|
||||
let flags =
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED;
|
||||
if unsafe { SetWindowPos(window, std::ptr::null_mut(), 0, 0, 0, 0, flags) } == 0 {
|
||||
log::error!("blur: DWM hears of no new frame after the move");
|
||||
}
|
||||
}
|
||||
}
|
||||
WM_NCDESTROY => {
|
||||
unsafe { RemovePropW(window, BLURRED) };
|
||||
unsafe { RemovePropW(window, MOVING) };
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ What no check reached: no real KWin drew the blur; of Wayland desktops, only Hyp
|
||||
| OSC 8 and plain links on Cmd-press, Ctrl-press off macOS; inside herdr, herdr opens them whole | T09, T45 | `term::links` tests; on macOS with real herdr 0.9.5 and a stand-in `open` on its PATH, Cmd-press on a URL herdr wraps, on its wrapped tail, on an OSC 8 link and on a URL over three rows opened the whole URL and the OSC 8 target, where before the app opened `.../ELYTermin` and nothing; Cmd-hover underlined the long URL across its rows; outside herdr the app opened the URL itself; an OSC 8 link whose label holds `file:///etc/hosts` and whose target is a web page opened the page through herdr, which keeps the target from the terminal while it takes the mouse; Shift-Cmd-press on a plain `file:///etc/hosts` inside herdr the app opened itself, caught by an `NSWorkspace` stand-in | Pass |
|
||||
| Focus reporting, title, scrollback limit, find | T10 | `term::find` tests; round 3 failed at the cap, its fix stands on a red-green test | Pass |
|
||||
| A scrollbar over the history: a drag on its thumb scrolls, whatever the program does with the wheel | T58 | `term::scrollbar` test: the thumb's share and place follow the history and the view's offset, and a place past either end of the track holds at it; under Xorg's dummy screen, after `seq 1 500`, the thumb stood at the bottom right, a drag to the top showed the first prompt and lines 1 to 39, and one back down lines 220 to 259; with mouse tracking on, the wheel went to the program as reports and did not scroll, while a drag on the thumb showed lines 245 to 284 | Pass |
|
||||
| Windows 10: dragging a blurred window follows the pointer, its acrylic clear while it moves | T65 | on the owner's Windows 11 PC (build 26300) the release path logged `blur: Windows build 26300 moves acrylic as it is`; a probe build with the build check raised logged `acrylic clears while the window moves`, and a drag by the terminal's header moved the window 180 by 90 pixels, logged `the window moves clear` and `the window rests blurred again`, and pictured clear glass mid-drag and acrylic at rest; Windows 10 went untested | Pass |
|
||||
| Windows 10: dragging a blurred window follows the pointer, its acrylic clear while it moves | T65 | on the owner's Windows 11 PC (build 26300) the release path logged `blur: Windows build 26300 moves acrylic as it is`; a probe build with the build check raised logged `acrylic clears while the window moves`, and a drag by the terminal's header moved the window 180 by 90 pixels, logged `the window moves clear` and `the window rests blurred again`, and pictured clear glass mid-drag and acrylic at rest; round 1 of T65's review found that blur turned on mid-move, which gpui sets as acrylic at once, kept acrylic for the rest of the move: a moving mark now clears it again, and the reviewer's replay of the procedure and the blur's changes against recorded Win32 calls passed its 9 cases, a blur turned on and on again mid-move among them; the drag on the PC logged both switches again; Windows 10 went untested | Pass |
|
||||
| IME on Windows: the candidate box at the caret | T61 | on the owner's Windows 11 PC at 150%, WeType under powershell.exe: 23 compositions, on one line, on lines below, begun again at once after a commit, and under a status line redrawn every 100 ms, each logged `the input method asks for the caret` at the cursor's cell and drew the box under it; the user's jump did not reproduce and the owner closed it | Closed |
|
||||
| Drop: files dropped on the terminal type their paths at the cursor, kept literal for the session's shell, each followed by a space | T66 | `term::drop` tests: a POSIX path escapes what a shell reads specially, spaces, quotes, parentheses, `&`, `$`, `^`, `~` and `#` among them, CJK kept, each path followed by a space; a PowerShell path is single-quoted with its quotes doubled, curly ones too; a cmd path is double-quoted, and one holding `%` types nothing; a path with a control character types nothing; `term::shell` test: zsh, fish and other shells take POSIX quoting, pwsh and powershell PowerShell's, cmd cmd's; round 1 of T66's review found Windows' quotes around a spaced path alone leaving `$(...)` and `;` live in PowerShell, and `^` unescaped under zsh's `extendedglob`: the formatter, extracted, typed 22 hard names that zsh with and without `extendedglob`, bash with `extglob`, fish and PowerShell each read back exactly, `it's`, `$HOME`, `$(1+1)`, `a;Write-Output(42)` and curly quotes among them, and cmd on the owner's PC echoed `&`, `|`, `<`, `>` and `^` inside its quotes back as text while it expanded `%PATH%`; round 2 found cmd's `/v:on` expanding `!` inside quotes, and `"C:\"` read by a program as one argument with the next: a `!` now stops a cmd drop, and the backslashes ending a path are doubled, so node, run from a cmd batch line on the owner's PC, received `C:\`, `D:\clip.mp4`, `C:\My Files\a&b^c.txt`, `C:\x|y<z>(1).txt`, `C:\dir with space\` and `C:\tmp\a;b,c=d.txt` exactly; on macOS `shot` dropped `/tmp/my file.png`, `/Users/x/it's (1).txt` and `/a/中文 b` on zsh after a pointer move, and the log read `3 paths dropped` and `pastes 53 characters, bracketed`; without the move, after typing, gpui passed the drop by, as AGENTS records | Pass |
|
||||
| Click to move: a plain click on the line the shell reads, past its prompt, moves its cursor there, the press itself to a shell that takes clicks, else arrows | T59 | `term::marks` test: A's `click_events=1` and `2` read as a press at the screen's row or counted from the prompt; `term::click` tests: a shell that takes clicks hears an SGR left press at the clicked cell, a row below the prompt too, none before the prompt, in the history or on the alternate screen; B reads the line its prompt started; a click on the typed line counts the characters to it, left or right, past the end means the end, a wide character takes one arrow, soft-wrapped rows are one line, trailing spaces count up to the cursor, and a click on the prompt, another line, a line no prompt shows, output without marks or the alternate screen moves nothing; on macOS `shot` ran zsh with a marked prompt: after `echo hello` a click on the `h` logged `moves the cursor -5`, and `X` typed then ran `echo Xhello`; a drag sent nothing, and clicks on the prompt and on output logged `off the input`; round 1 of T59's review found fish 4.9 a code point per Left, so a count put `X` inside `é`, and its redraw dropped the wrap flag a count followed: with fish's own `click_events=1` the press goes to fish, which then typed `echo Xéabc`, and a second click on the redrawn wrapped line put `Y` at row 2, column 3; zsh still counted 4 arrows; a press let go in another cell and one whose program turned on tracking before the release sent nothing; round 2 found a click on fish's `$` sent to fish, which moved its cursor to the start: a press now goes only past the prompt's last cell before the cursor and never on a prompt cell, so clicks on `$` and its space logged `off the input` and `X` still ended `echo helloX`; round 3 found that a prompt whose only cells lie after the cursor, fish's empty left prompt beside a marked right one, crashed the press: with no prompt cell before the cursor the input starts at the prompt's first row, and a click on `o` there put `X` at `echXo`; round 3 found that a prompt that prints nothing left no cells to find the input by, so clicks on fish's typed line did nothing: B now stamps the typed line with a link of its own, numbered by the commands ended, so fish's empty prompt gave `abcXdef`, with a plain or no right prompt too, a click on the output above moved nothing, and fish's right prompt drawn again at each key kept the typed line's number, `echXo`; `term::prompts` test: input carries the commands ended before it, through a prompt drawn again; `term::click` tests: a prompt that prints nothing starts the input at its first typed cell, the output and the line run before refused; round 4 found the newest typed line taken by its place: after `printf '\e[H'` fish drew its prompt at the top over older lines, and a click on its typed line did nothing; the newest line is now the one of the highest number, and a press goes no lower than its last row or the cursor's, so that click gave `abcXdef`, the reviewer's scene sent `ESC[<0;6;1M`, and a click on the older text below moved nothing, where fish had moved its cursor | Pass |
|
||||
|
||||
Reference in new issue
Block a user