From efe5d4fc5da5150ab40a492656383761f80ffe1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Fri, 9 Oct 2026 04:02:29 -0400 Subject: [PATCH] ElyShow: the show is native fullscreen off macOS, simple fullscreen on it (R2.5) --- apps/ely-show/src/slideshow/start.rs | 44 ++++++++++++++++++++++++---- tasks/reviews/R2.5-r1.md | 3 ++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tasks/reviews/R2.5-r1.md diff --git a/apps/ely-show/src/slideshow/start.rs b/apps/ely-show/src/slideshow/start.rs index 311f5ae..b34e401 100644 --- a/apps/ely-show/src/slideshow/start.rs +++ b/apps/ely-show/src/slideshow/start.rs @@ -18,8 +18,8 @@ use ely_lok::{Doc, Worker, show::ShowSlide}; use ely_office::prelude::*; use ely_platform::AppId; use gpui::{ - AnyElement, AnyWindowHandle, App, AppContext as _, Context, Entity, EntityId, IntoElement, - ParentElement as _, PlatformDisplay, Window, WindowBounds, WindowOptions, + AnyElement, AnyWindowHandle, App, AppContext as _, Bounds, Context, Entity, EntityId, IntoElement, + ParentElement as _, Pixels, PlatformDisplay, Window, WindowBounds, WindowOptions, }; use super::{Show, audience::Audience, presenter::Presenter}; @@ -80,9 +80,20 @@ fn copy( } } +/// macOS covers its menu bar and Dock by simple fullscreen. +const SIMPLE: bool = cfg!(target_os = "macos"); + +/// A show window's bounds: fullscreen, or macOS's simple kind. +fn bounds(area: Bounds) -> WindowBounds { + match SIMPLE { + true => WindowBounds::Windowed(area), + false => WindowBounds::Fullscreen(area), + } +} + fn options(display: &Rc) -> WindowOptions { WindowOptions { - window_bounds: Some(WindowBounds::Windowed(display.bounds())), + window_bounds: Some(bounds(display.bounds())), display_id: Some(display.id()), titlebar: None, focus: true, @@ -91,6 +102,13 @@ fn options(display: &Rc) -> WindowOptions { } } +/// Hides the menu bar and Dock over a macOS show. +fn cover(window: &mut Window) { + if SIMPLE { + window.toggle_simple_fullscreen(); + } +} + /// Opens one show window; its root scope holds the keys. pub fn show_window( show: &Entity, @@ -102,8 +120,7 @@ pub fn show_window( Ok(match presenter { true => cx .open_window(options(display), |window, cx| { - // Hides the menu bar and Dock over the show. - window.toggle_simple_fullscreen(); + cover(window); let view = cx.new(|cx| Presenter::new(show, cx)); window.focus(&view.read(cx).focus.clone(), cx); view @@ -111,7 +128,7 @@ pub fn show_window( .into(), false => cx .open_window(options(display), |window, cx| { - window.toggle_simple_fullscreen(); + cover(window); let view = cx.new(|cx| Audience::new(show, cx)); window.focus(&view.read(cx).focus.clone(), cx); view @@ -316,3 +333,18 @@ impl Deck { .into_any_element() } } + +#[cfg(test)] +mod tests { + use gpui::{Bounds, WindowBounds, point, px, size}; + + #[test] + fn a_show_covers_the_display_on_every_platform() { + let area = Bounds::new(point(px(0.), px(0.)), size(px(1920.), px(1080.))); + let want = match cfg!(target_os = "macos") { + true => WindowBounds::Windowed(area), + false => WindowBounds::Fullscreen(area), + }; + assert_eq!(super::bounds(area), want); + } +} diff --git a/tasks/reviews/R2.5-r1.md b/tasks/reviews/R2.5-r1.md new file mode 100644 index 0000000..5fb155a --- /dev/null +++ b/tasks/reviews/R2.5-r1.md @@ -0,0 +1,3 @@ +FAIL + +apps/ely-show/src/slideshow/start.rs:85:Windows/Linux 放映退化为普通窗口,违反 PRD SHOW-11。这里把所有平台的初始状态改为 `WindowBounds::Windowed`,两个窗口分支随后只调用 `toggle_simple_fullscreen()`(106、114 行)。锁定的 GPUI 0.3.8 将该方法定义为 macOS 专用,Windows、X11、Wayland 均沿用空实现。具体场景:Windows 开着任务栏时按 F5,观众窗口保持普通窗口,任务栏可覆盖幻灯片;Windows 后端创建普通窗口时还设定 `NonRudeHWND=true`,原生全屏路径才会解除该标记。Linux 同样遗漏向窗口管理器请求全屏,演讲者窗口也受影响。已独立构建应用和 worker、跑完 75 项应用测试与 Metal compose 测试;编译运行使用同一默认方法的 GPUI 后端对照探针,提交前得到 `fullscreen=true`,提交后得到 `fullscreen=false`,SHOW-11 全屏断言退出 101(证据:`/tmp/ely-r25-verification.log`、`/tmp/ely-r25-fullscreen-assert.log`)。macOS 真窗口两次启动、黑屏、Esc 退出通过。修复方向:macOS 使用 simple fullscreen,其他平台保留 `WindowBounds::Fullscreen` 或调用原生全屏接口,并补充能断言窗口实际进入全屏的回归测试。