X11:无边框窗口逐帧 glfwSetWindowPos 拖动被 WM 钳制在屏幕内;Wayland 构建无法拖动
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 18/100
Línea de trabajo
Start with the public surface in include/eui/window.h and the core::window implementation, then trace how the title-bar drag currently calls glfwSetWindowPos each frame. The proposed beginWindowMove and beginWindowResize would need a per-backend implementation: X11 via _NET_WM_MOVERESIZE, with Wayland and Windows/macOS returning false. Done means beginWindowMove returns true on X11 so the app drops its own drag loop, while other backends return false and the existing per-frame fallback still works.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
X11:无边框窗口用逐帧 glfwSetWindowPos 拖动会被窗口管理器钳制在屏幕内;Wayland 构建则完全无法拖动
EUI-NEO v0.6.0-dev(ff1e757),bundled GLFW(GLFW_BUILD_X11=ON / GLFW_BUILD_WAYLAND=OFF),无边框窗口(.decorated(false))+ 自绘标题栏。Ubuntu 24.04,GNOME 46 Wayland 会话(XWayland),Mutter 46.2。
复现方式
使用 .decorated(false) 的应用按常规方式实现自绘标题栏拖动:
- 在标题栏按下时记录窗口原点与指针原点。
- 拖动过程中每帧调用
glfwSetWindowPos(window, startX + dx, startY + dy)。
预期:窗口跟随指针,并且和原生标题栏拖动一样可以拖出屏幕边缘(也能享受原生贴边分屏)。
实际:窗口只在完全位于工作区内时跟随指针;到达任意屏幕边缘就卡住,永远无法超出。同样的代码在原生 Wayland GLFW 构建下拖动完全无效。
根因
- X11:
glfwSetWindowPos每帧发起XMoveWindow,每次移动都以客户端ConfigureRequest形式到达窗口管理器。Mutter 将其视为非用户动作的配置请求,由constrain_fully_onscreen(src/core/constraints.c,优先级PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA)把位置推回可用显示器区域。该约束的豁免条件恰好解释了为什么 WM 原生拖动不受影响:info->is_user_action(交互式移动)、dock/desktop 窗口、全屏窗口。逐帧XMoveWindow循环在 WM 眼里不是用户动作,于是被钳制。 - Wayland:客户端根本没有定位权限,
_glfwSetWindowPosWayland是文档化的 no-op(GLFW_FEATURE_UNAVAILABLE),这种拖动循环在原理上就不可能工作。唯一正确的机制是xdg_toplevel.move。
所以这不是 GLFW 或 WM 的 bug,而是缺失的窗口能力:拥有自绘 chrome 的 EUI 应用没有任何途径把拖动交给合成器,而每个无边框应用要么接受边缘钳制,要么自己在应用层重写一遍 WM 协议代码。
建议方案
在 core::window 增加一个小能力,经 include/eui/window.h 暴露:
namespace eui::window {
// 请窗口管理器/合成器接管交互式移动/缩放。
// 当前平台/后端无法委托时返回 false,调用方保留自己的程序化回退。
bool beginWindowMove(Handle window);
bool beginWindowResize(Handle window, WindowResizeEdge edge);
}
- GLFW/X11:向根窗口发送 EWMH
_NET_WM_MOVERESIZEClientMessage(direction 8 = MOVE,或对应SIZE_*方向;source indication 1 = application;指针根坐标用XQueryPointer获取),发送前按规范先释放按钮的隐式 grab。之后由 WM 执行交互式移动/缩放:无逐帧往返、允许部分拖出屏幕、原生吸附/分屏白拿。 - GLFW/Wayland:
xdg_toplevel.move/resize需要按下时的 seat serial,只有后端内部持有。如果暂时拿不到,就返回false并在文档说明;X11 构建已经能拿到正确行为。 - SDL2/X11:经
SDL_SysWMinfo发送同一条消息。 - Windows/macOS:返回
false(程序化循环在这些平台本来就可用)。
应用侧只需改一行:标题栏按下时调用 beginWindowMove,返回 true 就停用自己的拖动循环。
验收标准
- GNOME / XWayland:无边框窗口按自绘标题栏拖动可以拖出屏幕边缘,并像原生拖动一样触发贴边分屏。
- 自绘边缘拖手缩放同样委托给 WM。
- 无法满足的平台/后端返回
false,既有逐帧回退保持可用。 - 有边框窗口与非 Linux 平台行为不变。
- Lenguaje dominante
- C++
- Estrellas
- 2k
- Forks
- 177
- Merge medio
- 2 d 1 h
- PR fusionados (30 d)
- 13
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de sudoevolve/EUI-NEO
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
sudoevolve/EUI-NEO#110 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 20/100
sudoevolve/EUI-NEO#113 ·
Los mantenedores suelen responder en 2 días
-
Windows transparent margins composite as black: bundled GLFW redirection alpha is uninitializedPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 22/100
sudoevolve/EUI-NEO#109 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 32/100
sudoevolve/EUI-NEO#106 ·
Los mantenedores suelen responder en 2 días
-
Android分支仍然不支持Windows触摸Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
sudoevolve/EUI-NEO#45 · 5 comentarios ·
Los mantenedores suelen responder en 2 días
Todos los issues de sudoevolve/EUI-NEO
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
foxglove/mcap#1907 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
telegramdesktop/tdesktop#31505 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
ll-builder shell completions omit existing lockfile commands and --lockedPosiblemente ocupada @project-nju-learner la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 90/100
OpenAtom-Linyaps/linyaps#2291 ·
Los mantenedores suelen responder en 1 día