X11:无边框窗口逐帧 glfwSetWindowPos 拖动被 WM 钳制在屏幕内;Wayland 构建无法拖动
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 18/100
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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 平台行为不变。
- Lingua principale
- C++
- Stelle
- 2k
- Fork
- 177
- Merge medio
- 19h 58m
- PR unite (30g)
- 9
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di sudoevolve/EUI-NEO
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
sudoevolve/EUI-NEO#110 ·
I maintainer di solito rispondono entro 2 giorni
-
在linux上使用触摸屏没法直接滑动翻页Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
sudoevolve/EUI-NEO#116 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 20/100
sudoevolve/EUI-NEO#113 ·
I maintainer di solito rispondono entro 2 giorni
-
Windows transparent margins composite as black: bundled GLFW redirection alpha is uninitializedForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
sudoevolve/EUI-NEO#109 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 32/100
sudoevolve/EUI-NEO#106 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di sudoevolve/EUI-NEO
Issue simili
-
v9.6.0: CMake incorrectly enforces presence of libevdevForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 65/100
mltframework/shotcut#1943 ·
I maintainer di solito rispondono entro 1 giorno
-
Rowan (2017) electron heating gives NaN for beta > beta_max; clip() then sets electrons to kel_minAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
parthenon-hpc-lab/kharma#213 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
metasequoiaime/msime#9113 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
tone-3000/tone3000-plugin#257 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno