Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

X11:无边框窗口逐帧 glfwSetWindowPos 拖动被 WM 钳制在屏幕内;Wayland 构建无法拖动

Abierto
#89 1 comentario 0 reacciones 0 asignados Ver en GitHub

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
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
cpp, linux
Área
desktop

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) 的应用按常规方式实现自绘标题栏拖动:

  1. 在标题栏按下时记录窗口原点与指针原点。
  2. 拖动过程中每帧调用 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_MOVERESIZE ClientMessage(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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de sudoevolve/EUI-NEO

Todos los issues de sudoevolve/EUI-NEO

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.