T51: Ely stands inside the main window on its pane's bottom edge while her box would not fit above it, which the owner asked for after 0.1.4, where on a window at the screen's top or full screen she stuck between the menu bar and the terminal: each platform measures the room above the pane up to its display's work area, macOS's visibleFrame, Windows' rcWork, X11's _NET_WORKAREA, and on Wayland, which tells a client no place, she stands inside while the window is full screen, maximized or tiled at its top
CI / platforms (windows-latest) (push) Successful in 1m38s
CI / platforms (ubuntu-24.04) (push) Successful in 2m21s
CI / macos (push) Successful in 12m50s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-19 01:55:59 -04:00
1 parent 7032285d13
commit 15ef5d52d0
10 files changed
+291 -98

No files matched your search

+30 -15
View File
@@ -1,4 +1,4 @@
//! Ely's window on Windows: a bare popup owned by the main window, so it stays above it and hides with it, sized and moved as it moves.
//! Ely's window on Windows: a bare popup owned by the main window, so it stays above it and hides with it, sized and moved onto an edge of its pane as it moves.
use std::{
cell::Cell,
@@ -10,7 +10,9 @@ use gpui::{Bounds, Pixels, Window};
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use windows_sys::Win32::{
Foundation::{HWND, LPARAM, LRESULT, RECT, WPARAM},
Graphics::Gdi::{MONITOR_DEFAULTTONEAREST, MonitorFromRect},
Graphics::Gdi::{
GetMonitorInfoW, MONITOR_DEFAULTTONEAREST, MONITORINFO, MonitorFromRect, MonitorFromWindow,
},
UI::{
HiDpi::{GetDpiForMonitor, GetDpiForWindow, MDT_EFFECTIVE_DPI},
WindowsAndMessaging::{
@@ -23,7 +25,7 @@ use windows_sys::Win32::{
},
};
use super::{HEAD, ROOM, WIDTH, left, pane};
use super::{Edge, HEAD, ROOM, WIDTH, edge, left, pane};
#[cfg(test)]
mod tests;
@@ -75,33 +77,46 @@ impl Glue {
Ok(Self { pet, main })
}
/// Stands her on the main window's top edge, as far in as its width allows.
pub fn place(&self, main: &Window) -> anyhow::Result<()> {
/// Stands her on the main window's top edge while her box fits under the top of its display's work area, else on its bottom edge, as far in as its width allows, and gives the edge.
pub fn place(&self, main: &Window) -> anyhow::Result<Edge> {
self.put(main.scale_factor(), pane(main))
}
/// Posts her bottom left corner on `pane` at `scale`, in the main window's points; her window sizes her at the DPI it has when the place lands, as gpui did not when it opened her off the display.
fn put(&self, scale: f32, pane: Bounds<Pixels>) -> anyhow::Result<()> {
/// Posts her bottom left corner on an edge of `pane` at `scale`, in the main window's points; her window sizes her at the DPI it has when the place lands, as gpui did not when it opened her off the display.
fn put(&self, scale: f32, pane: Bounds<Pixels>) -> anyhow::Result<Edge> {
let mut main = WINDOWINFO {
cbSize: size_of::<WINDOWINFO>() as u32,
..Default::default()
};
let read = unsafe { GetWindowInfo(self.main, &mut main) };
anyhow::ensure!(read != 0, "pet: the main window's place does not read");
let corner = stand(main.rcClient, scale, pane);
let mut display = MONITORINFO {
cbSize: size_of::<MONITORINFO>() as u32,
..Default::default()
};
let monitor = unsafe { MonitorFromWindow(self.main, MONITOR_DEFAULTTONEAREST) };
let read = unsafe { GetMonitorInfoW(monitor, &mut display) };
anyhow::ensure!(read != 0, "pet: the main window's display does not read");
let (_, top) = stand(main.rcClient, scale, pane, Edge::Top);
let edge = edge((top - display.rcWork.top) as f32 / scale);
let corner = stand(main.rcClient, scale, pane, edge);
let posted = unsafe { PostMessageW(self.pet, PLACE, pack(corner), 0) };
anyhow::ensure!(posted != 0, "pet: her place does not post");
log::debug!("pet: Ely is to stand on {corner:?}");
Ok(())
log::debug!("pet: Ely is to stand on {corner:?}, the pane's {edge:?} edge");
Ok(edge)
}
}
/// Her bottom left corner on `pane` at `scale` over the main window's `client` rect, in pixels.
fn stand(client: RECT, scale: f32, pane: Bounds<Pixels>) -> (i32, i32) {
let (x, y) = (f32::from(pane.origin.x), f32::from(pane.origin.y));
/// Her bottom left corner on `edge` of `pane` at `scale` over the main window's `client` rect, in pixels.
fn stand(client: RECT, scale: f32, pane: Bounds<Pixels>, edge: Edge) -> (i32, i32) {
let y = match edge {
Edge::Top => pane.origin.y,
Edge::Bottom => pane.bottom(),
};
let x = f32::from(pane.origin.x) + left(pane.size.width);
(
client.left + ((x + left(pane.size.width)) * scale).round() as i32,
client.top + (y * scale).round() as i32,
client.left + (x * scale).round() as i32,
client.top + (f32::from(y) * scale).round() as i32,
)
}