Compare commits

...

6 Commits

Author SHA1 Message Date
halx99
3e8d6484b2
Merge f1284eb884 into 7ef6efeb66 2025-08-19 11:14:12 +08:00
Camilla Löwy
7ef6efeb66 Wayland: Fix cursor position after a modal
If a modal surface like the window menu was active, clicking on the GLFW
window content area to close it would correctly emit the cursor enter
event but would not propagate the cursor position from the event.
2025-08-18 20:58:12 +02:00
Camilla Löwy
3cf9f6726d Wayland: Fix fallback decoration cursor updating
When a click through to the fallback decorations caused the end of
a modal like the window menu, the cursor shape would not be updated
until the next time the cursor moved.

This commit adds an update of the cursor for the pointer enter event for
fallback decoration surfaces, in addition to the updates at pointer
motion events.
2025-08-18 18:06:46 +02:00
Camilla Löwy
bfa1c424e5 Wayland: Fix fallback decoration menu placement
The fallback decorations would place the menu at the wrong position, by
not translating the last decoration surface position into toplevel
surface coordinates.

This also limits the menu to the caption area of the top decoration
surface, similar to how other toolkits work.
2025-08-18 18:06:46 +02:00
halx99
f1284eb884 Fix create as child window style 2024-03-01 21:49:49 +08:00
halx99
a94c9782d5 Add create glfw window as child support for win32 2024-03-01 21:49:49 +08:00
7 changed files with 66 additions and 15 deletions

View File

@ -139,6 +139,11 @@ information on what to include when reporting a bug.
fallback decorations fallback decorations
- [Wayland] Bugfix: Fallback decorations would report scroll events - [Wayland] Bugfix: Fallback decorations would report scroll events
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568) - [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
- [Wayland] Bugfix: Fallback decorations would show menu at wrong position
- [Wayland] Bugfix: The cursor was not updated when clicking through from
a modal to a fallback decoration
- [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631) - [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface` - [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`

View File

@ -1129,6 +1129,7 @@ extern "C" {
/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint). /*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint).
*/ */
#define GLFW_WIN32_SHOWDEFAULT 0x00025002 #define GLFW_WIN32_SHOWDEFAULT 0x00025002
#define GLFW_WIN32_HWND_PARENT 0x00025003
/*! @brief Wayland specific /*! @brief Wayland specific
* [window hint](@ref GLFW_WAYLAND_APP_ID_hint). * [window hint](@ref GLFW_WAYLAND_APP_ID_hint).
* *
@ -3053,6 +3054,14 @@ GLFWAPI void glfwDefaultWindowHints(void);
*/ */
GLFWAPI void glfwWindowHint(int hint, int value); GLFWAPI void glfwWindowHint(int hint, int value);
/*! @brief Sets the specified window hint to the desired value.
*
* @since Added in version 3.4.x.
*
* @ingroup window
*/
GLFWAPI void glfwWindowHintPointer(int hint, void* value);
/*! @brief Sets the specified window hint to the desired value. /*! @brief Sets the specified window hint to the desired value.
* *
* This function sets hints for the next call to @ref glfwCreateWindow. The * This function sets hints for the next call to @ref glfwCreateWindow. The

View File

@ -425,6 +425,7 @@ struct _GLFWwndconfig
struct { struct {
GLFWbool keymenu; GLFWbool keymenu;
GLFWbool showDefault; GLFWbool showDefault;
void* handleParent;
} win32; } win32;
struct { struct {
char appId[256]; char appId[256];

View File

@ -355,6 +355,7 @@ typedef struct _GLFWlibraryWGL
typedef struct _GLFWwindowWin32 typedef struct _GLFWwindowWin32
{ {
HWND handle; HWND handle;
HWND handleParent;
HICON bigIcon; HICON bigIcon;
HICON smallIcon; HICON smallIcon;

View File

@ -45,6 +45,8 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
if (window->monitor) if (window->monitor)
style |= WS_POPUP; style |= WS_POPUP;
else else
{
if (!window->win32.handleParent)
{ {
style |= WS_SYSMENU | WS_MINIMIZEBOX; style |= WS_SYSMENU | WS_MINIMIZEBOX;
@ -58,6 +60,9 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
else else
style |= WS_POPUP; style |= WS_POPUP;
} }
else
style |= WS_CHILD;
}
return style; return style;
} }
@ -1387,7 +1392,7 @@ static int createNativeWindow(_GLFWwindow* window,
style, style,
frameX, frameY, frameX, frameY,
frameWidth, frameHeight, frameWidth, frameHeight,
NULL, // No parent window (HWND)wndconfig->win32.handleParent,
NULL, // No window menu NULL, // No window menu
_glfw.win32.instance, _glfw.win32.instance,
(LPVOID) wndconfig); (LPVOID) wndconfig);
@ -1487,6 +1492,8 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
window->win32.handleParent = wndconfig->win32.handleParent;
if (!createNativeWindow(window, wndconfig, fbconfig)) if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;

View File

@ -436,6 +436,18 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint); _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
} }
GLFWAPI void glfwWindowHintPointer(int hint, void* value)
{
_GLFW_REQUIRE_INIT();
switch (hint)
{
case GLFW_WIN32_HWND_PARENT:
_glfw.hints.window.win32.handleParent = value;
break;
}
}
GLFWAPI void glfwWindowHintString(int hint, const char* value) GLFWAPI void glfwWindowHintString(int hint, const char* value)
{ {
assert(value != NULL); assert(value != NULL);

View File

@ -405,13 +405,19 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
} }
else if (button == BTN_RIGHT) else if (button == BTN_RIGHT)
{ {
if (window->wl.xdg.toplevel) if (!window->wl.xdg.toplevel)
{ return;
if (window->wl.fallback.focus != window->wl.fallback.top.surface)
return;
if (ypos < GLFW_BORDER_SIZE)
return;
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial, _glfw.wl.seat, serial,
window->wl.cursorPosX, xpos,
window->wl.cursorPosY); ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
}
} }
} }
@ -1532,11 +1538,21 @@ static void pointerHandleEnter(void* userData,
window->wl.hovered = GLFW_TRUE; window->wl.hovered = GLFW_TRUE;
_glfwSetCursorWayland(window, window->wl.currentCursor); _glfwSetCursorWayland(window, window->wl.currentCursor);
_glfwInputCursorEnter(window, GLFW_TRUE); _glfwInputCursorEnter(window, GLFW_TRUE);
if (window->cursorMode != GLFW_CURSOR_DISABLED)
{
window->wl.cursorPosX = wl_fixed_to_double(sx);
window->wl.cursorPosY = wl_fixed_to_double(sy);
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
}
} }
else else
{ {
if (window->wl.fallback.decorations) if (window->wl.fallback.decorations)
{
window->wl.fallback.focus = surface; window->wl.fallback.focus = surface;
updateFallbackDecorationCursor(window, sx, sy);
}
} }
} }