
Electron Rectangle 对象详解窗口定位、多显示器 bounds 与 DIP 坐标体系【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron本文以 Electron 官方文档 Rectangle Object 为主体完整讲清Rectangle结构体的四个字段x、y、width、height均为整数、它所处的 DIP 坐标系语义以及该结构在screen、BrowserWindow等 API 中的真实出现位置与底层 C 实现链路。读完你可以正确编写多显示器窗口定位逻辑、理解窗口/显示器几何数据在主进程与底层 Chromiumgfx::Rect之间的转换机制并掌握bounds相关事件的整数坐标约束。一、Rectangle 结构体字段定义根据 docs/api/structures/rectangle.mdRectangle对象的完整定义为字段类型说明约束xnumber矩形原点origin的 x 坐标必须是整数must be an integerynumber矩形原点的 y 坐标必须是整数widthnumber矩形的宽度必须是整数heightnumber矩形的高度必须是整数即一个Rectangle值形如const rect { x: 100, y: 200, width: 640, height: 480 };有两条语义要点需要注意整数约束文档明确要求四个字段都是整数。这不是排版习惯而是源于底层实现——Electron 的几何数据最终落到 Chromium 的gfx::Rect整型几何类型上浮点坐标会在转换环节被取整。因此向 API 传入{ x: 10.5, ... }时不应假设其被原样保留。坐标单位为 DIPRectangle通常描述显示器或窗口在虚拟桌面坐标系中的位置和尺寸。以Display对象为例docs/api/structures/display.md 明确标注bounds与workArea两个Rectangle字段是 the bounds of the displayin DIP points以设备无关像素为单位。与 Point、Size 的配套关系同一目录下的 point.md 与 size.md 定义了配套的几何结构Point描述原点x/ySize描述尺寸width/height。Display对象中同时出现boundsRectangle、sizeSize、workAreaSizeSize、nativeOriginPoint等字段实际编程中常见用boundsRectangle取位置 workAreaSizeSize取尺寸的组合用法。二、Rectangle 在 API 中的主要出现位置Rectangle是 Electron API 中最核心的几何结构之一通过全文检索文档它在多个高频接口中出现1. Display 对象bounds与workAreaDisplay 结构体由screen.getPrimaryDisplay()、screen.getAllDisplays()返回中包含两个RectangleboundsRectangle —— 显示器在 DIP 点中的完整边界workAreaRectangle —— 显示器工作区排除任务栏等系统占用区域的 DIP 点边界。官方 screen 模块文档 给出了两个经典实战示例。示例一创建充满主屏工作区的窗口对应 docs/fiddles/screen/fit-screen 中的可运行 fiddleconst { app, BrowserWindow, screen } require(electron/main) let mainWindow null app.whenReady().then(() { // Create a window that fills the screens available work area. const primaryDisplay screen.getPrimaryDisplay() const { width, height } primaryDisplay.workAreaSize mainWindow new BrowserWindow({ width, height }) mainWindow.loadURL(https://electronjs.org) })示例二把窗口定位到外接显示器——这里直接消费bounds这个Rectangle的x/y字段是理解 Rectangle 语义最直观的片段const { app, BrowserWindow, screen } require(electron) let win app.whenReady().then(() { const displays screen.getAllDisplays() const externalDisplay displays.find((display) { return display.bounds.x ! 0 || display.bounds.y ! 0 }) if (externalDisplay) { win new BrowserWindow({ x: externalDisplay.bounds.x 50, y: externalDisplay.bounds.y 50 }) win.loadURL(https://github.com) } })其技巧是主显示器的bounds.x和bounds.y通常为0因此bounds.x ! 0 || bounds.y ! 0可以筛出非主屏再把窗口放到外接屏左上角偏移 50 DIP 的位置。2. BrowserWindowgetBounds()、getNormalBounds()与事件BrowserWindow 文档 中Rectangle密集出现覆盖窗口几何的读写与事件win.getBounds()—— ReturnsRectangle- Theboundsof the window asObjectwin.getNormalBounds()—— 返回窗口在正常状态未最大化/最小化/全屏时的Rectangle文档特别指出在 normal state 下getBounds与getNormalBounds返回相同的Rectangleresize-event的newBounds—— Size the window is being resized to类型为Rectanglemove事件的newBounds—— Location the window is being moved to类型为Rectanglewin.setBounds(bounds)—— 参数bounds为RectanglecapturePage(rect)—— 可选的rect参数为Rectangle指定截取的窗口区域setShape(rects)——rects为Rectangle[]用于设置窗口形状win.setBounds相关文档还出现PartialRectangle形式即只允许传部分字段如只改x/y而不动width/height。这类事件回调是窗口状态持久化参考 docs/tutorial/window-state-persistence.md 的思路的直接数据来源在resize/move事件中读取newBounds这个Rectangle写入用户配置启动时再用setBounds还原。3. screen 模块显示器匹配与 DIP/物理像素矩形互转screen 文档 中Rectangle是两组方法的核心参数与返回值screen.getDisplayMatching(rect)—— 参数rect为Rectangle返回与该矩形相交最多的显示器screen.screenToDipRect(window, rect)Windows—— 参数与返回值均为Rectangle把物理像素矩形转换为 DIP 矩形screen.dipToScreenRect(window, rect)Windows—— 反向转换。这两组方法解决多 DPI 环境下的经典问题当窗口跨越不同缩放比例的显示器时同一份矩形数据在物理像素与DIP下数值不同必须按所在显示器做缩放。文档同时强调对应 docs/api/screen.md 中的 NOTEscreen模块的坐标分为物理屏幕点raw hardware pixels与DIP 点按 DPI 缩放的虚拟点两种模块常规返回值是 DIP 点而非物理点。三、底层实现从 gfx::Rect 到 JS 对象的转换链路文档只定义了 JS 侧的四个字段而从源码结构看Rectangle之所以是整数语义、且能在 JS 与 C 之间无缝传递依赖 Electron 为 Chromiumgfx几何类型注册的 gin 转换器。1. gin::Convertergfx::Rect 的定义在 shell/common/gin_converters/gfx_converter.h 中Electron 为gfx::Rect专门实例化了 gin 的Converter模板template struct Convertergfx::Rect { static v8::Localv8::Value ToV8(v8::Isolate* isolate, const gfx::Rect val); static bool FromV8(v8::Isolate* isolate, v8::Localv8::Value val, gfx::Rect* out); };这解释了文档中 must be an integer 约束的由来输出方向ToV8C 侧的gfx::Rect其成员本身即整型被序列化为带x、y、width、height属性的普通 JS 对象——即文档定义的那个Rectangle输入方向FromV8JS 传入的对象被反向解析回gfx::Rect。由于目标是整型几何类型从源码结构看可以推断非整数坐标会经历取整/校验处理因此在编写窗口定位逻辑时应始终使用整数坐标避免依赖浮点行为。同一头文件还为gfx::Point、gfx::PointF、gfx::Size、gfx::Insets、display::Display等类型注册了对应的Converter与 point.md、size.md、display.md 等结构体文档一一对应——每个 API 文档中的结构体在 C 侧都有一条这样的双向转换通道。2. screen 模块的 C 侧消费方式shell/browser/api/electron_api_screen.cc 展示了Rectangle在底层如何被消费Screen::GetDisplayMatching(const gfx::Rect match_rect)见 electron_api_screen.cc直接接收gfx::Rect并转发给 Chromium 的display::Screen::GetDisplayMatching——也就是说 JS 端screen.getDisplayMatching(rect)传入的Rectangle在 C 侧就是一个gfx::Rectdisplay-metrics-changed事件的changedMetrics数组由MetricsToArray生成见 electron_api_screen.cc其中DISPLAY_METRIC_BOUNDS映射为字符串bounds、DISPLAY_METRIC_WORK_AREA映射为workArea——正是Display里那两个Rectangle字段说明当显示器 bounds/workArea 发生变化时该事件会携带变更后的Display含新的bounds/workAreaRectangle与指标名发出screenToDipRect/dipToScreenRect在 Windows 上经由display::win::GetScreenWin()-ScreenToDIPRect / DIPToScreenRect实现见 electron_api_screen.cc与文档Windows平台标注一致测试层面spec/api-screen-spec.ts 验证了getAllDisplays至少返回一个显示器、getCursorScreenPoint返回x/y均为 number 等行为可作为 Rectangle/Point 结构实际取数行为的回归依据。3. 其他消费点shell/browser/api/electron_api_web_contents.cc中window_features.bounds直接解构使用bounds.x()、bounds.y()见 electron_api_web_contents.cc 附近代码体现Rectangle/Rect数据在窗口 features如setWindowBounds相关链路中的流转shell/browser/native_window_views.cc中 Linux/X11 窗口形状处理使用x11::Rectangle见 native_window_views.cc说明在 X11 平台上 Rectangle 语义还会直接映射到窗口系统的 shape 扩展。四、实战要点与常见陷阱小结只用整数构造Rectangle时统一取整Math.round/Math.floor与文档 must be an integer 约束及底层gfx::Rect的整型语义保持一致。区分 DIP 与物理像素Display.bounds、win.getBounds()、resize/move事件的newBounds都是 DIP 坐标仅在 Windows 的screenToDipRect/dipToScreenRect等显式转换方法中才涉及物理像素。跨 DPI 多屏场景必须先判断矩形所在显示器再换算。多屏定位用screen.getAllDisplays() 各display.boundsRectangle的x/y判断主/副屏如上文示例二所示bounds.x ! 0 || bounds.y ! 0是官方文档推荐的外接屏识别技巧。响应显示器变化监听screen的display-metrics-changed事件根据changedMetrics中的bounds/workArea字符串判断是哪个Rectangle字段发生了变化再重算窗口位置MetricsToArray的实现证实了这两个字符串值见 electron_api_screen.cc。PartialRectangle用法BrowserWindow文档中部分接口接受PartialRectangle允许只传x/y移动窗口或只传width/height缩放窗口无需凑齐四个字段。五、参考资料仓库内路径结构体定义docs/api/structures/rectangle.md、point.md、size.md、display.md消费方文档docs/api/screen.md、docs/api/browser-window.md、docs/tutorial/window-state-persistence.md可运行示例docs/fiddles/screen/fit-screen底层实现shell/common/gin_converters/gfx_converter.h、shell/browser/api/electron_api_screen.cc测试spec/api-screen-spec.ts【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考