T46: round 1 fixes: Ely's window never takes the keys, a panel key only if needed on macOS and on Windows a window that answers a press's activation with none; she opens with the sessions' mood; she stands 140 points in or less on a narrow pane, so she holds its edge at any width, and on Wayland, whose popup keeps the place it opened at, she opens again when a new width moves her
CI / platforms (ubuntu-24.04) (push) Successful in 1m53s
CI / platforms (windows-latest) (push) Successful in 2m2s
CI / macos (push) Canceled after 9m52s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-18 05:26:13 -04:00
1 parent 9aeb3f3552
commit 6df7534e7f
7 files changed
+165 -70

No files matched your search

+32 -8
View File
@@ -1,17 +1,23 @@
//! Ely's window on Windows: owned by the main window, so it stays above it and hides with it, and moved as it moves.
use std::sync::atomic::{AtomicIsize, Ordering};
use anyhow::bail;
use gpui::Window;
use gpui::{Window, px};
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use windows_sys::Win32::{
Foundation::{HWND, RECT},
Foundation::{HWND, LPARAM, LRESULT, RECT, WPARAM},
UI::WindowsAndMessaging::{
GWLP_HWNDPARENT, GetWindowRect, HWND_NOTOPMOST, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE,
SWP_NOZORDER, SetWindowLongPtrW, SetWindowPos,
CallWindowProcW, GWLP_HWNDPARENT, GWLP_WNDPROC, GetWindowRect, HWND_NOTOPMOST,
MA_NOACTIVATE, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, SetWindowLongPtrW,
SetWindowPos, WM_MOUSEACTIVATE, WNDPROC,
},
};
use super::{HEAD, LEFT, ROOM};
use super::{HEAD, ROOM, left};
/// gpui's window procedure, which hers passes every message on to but a press's activation.
static GPUI: AtomicIsize = AtomicIsize::new(0);
/// Her window and the main one.
pub struct Glue {
@@ -20,11 +26,14 @@ pub struct Glue {
}
impl Glue {
/// Gives her window the main window as owner, and takes away the topmost place gpui gives a popup.
/// Gives her window the main window as owner, takes away the topmost place gpui gives a popup, and keeps a press from activating it, so the keys stay with the terminal.
pub fn new(pet: &Window, main: &Window) -> anyhow::Result<Self> {
let (pet, main) = (native(pet)?, native(main)?);
unsafe {
SetWindowLongPtrW(pet, GWLP_HWNDPARENT, main as isize);
let gpui = SetWindowLongPtrW(pet, GWLP_WNDPROC, inactive as *const () as isize);
anyhow::ensure!(gpui != 0, "pet: her window's procedure does not read");
GPUI.store(gpui, Ordering::Relaxed);
let flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE;
anyhow::ensure!(
SetWindowPos(pet, HWND_NOTOPMOST, 0, 0, 0, 0, flags) != 0,
@@ -34,7 +43,7 @@ impl Glue {
Ok(Self { pet, main })
}
/// Stands her on the main window's top edge, `LEFT` points in from its left.
/// Stands her on the main window's top edge, as far in as its width allows.
pub fn place(&self, main: &Window) -> anyhow::Result<()> {
let scale = main.scale_factor();
let mut frame = RECT::default();
@@ -43,7 +52,8 @@ impl Glue {
GetWindowRect(self.main, &mut frame) != 0,
"pet: the main window's place does not read"
);
let x = frame.left + (LEFT * scale).round() as i32;
let width = px((frame.right - frame.left) as f32 / scale);
let x = frame.left + (left(width) * scale).round() as i32;
let y = frame.top - ((HEAD + ROOM) * scale).round() as i32;
let flags = SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE;
anyhow::ensure!(
@@ -55,6 +65,20 @@ impl Glue {
}
}
/// Her window's procedure: a press does not activate her window; all else is gpui's.
unsafe extern "system" fn inactive(
window: HWND,
message: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
if message == WM_MOUSEACTIVATE {
return MA_NOACTIVATE as LRESULT;
}
let gpui: WNDPROC = unsafe { std::mem::transmute(GPUI.load(Ordering::Relaxed)) };
unsafe { CallWindowProcW(gpui, window, message, wparam, lparam) }
}
/// The HWND gpui made for `window`.
fn native(window: &Window) -> anyhow::Result<HWND> {
let handle = HasWindowHandle::window_handle(window)