mirror of
https://github.com/glfw/glfw.git
synced 2025-12-21 14:42:06 +00:00
Compare commits
11 Commits
daf918bf03
...
ad5480e1db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad5480e1db | ||
|
|
0d2d85d19c | ||
|
|
768e81a0eb | ||
|
|
161fb1b6f6 | ||
|
|
645a35a38e | ||
|
|
7523b0e6bd | ||
|
|
5190a30d8a | ||
|
|
ddbb8e0f2c | ||
|
|
5245180c56 | ||
|
|
c8bb716886 | ||
|
|
127ae123fe |
@ -68,6 +68,7 @@ video tutorials.
|
|||||||
- Jan Ekström
|
- Jan Ekström
|
||||||
- Siavash Eliasi
|
- Siavash Eliasi
|
||||||
- er-azh
|
- er-azh
|
||||||
|
- Jan Hendrik Farr
|
||||||
- Ahmad Fatoum
|
- Ahmad Fatoum
|
||||||
- Nikita Fediuchin
|
- Nikita Fediuchin
|
||||||
- Felipe Ferreira
|
- Felipe Ferreira
|
||||||
|
|||||||
@ -135,6 +135,10 @@ information on what to include when reporting a bug.
|
|||||||
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
|
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
|
||||||
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
|
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
|
||||||
- [Wayland] Bugfix: Keyboard leave event handler now processes key repeats (#2736)
|
- [Wayland] Bugfix: Keyboard leave event handler now processes key repeats (#2736)
|
||||||
|
- [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over
|
||||||
|
fallback decorations
|
||||||
|
- [Wayland] Bugfix: Fallback decorations would report scroll events
|
||||||
|
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
|
||||||
- [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`
|
||||||
|
|||||||
@ -262,6 +262,11 @@ This is the new name, introduced in GLFW 3.4. The older
|
|||||||
`GLFW_COCOA_RETINA_FRAMEBUFFER` name is also available for compatibility. Both
|
`GLFW_COCOA_RETINA_FRAMEBUFFER` name is also available for compatibility. Both
|
||||||
names modify the same hint value.
|
names modify the same hint value.
|
||||||
|
|
||||||
|
@anchor GLFW_THEME
|
||||||
|
__GLFW_THEME__ specifies whether the window should use light theme or not.
|
||||||
|
Possible values are `GLFW_THEME_AUTO`, `GLFW_THEME_DARK`, and `GLFW_THEME_LIGHT`. This hint only has effect
|
||||||
|
on windows operating system.
|
||||||
|
|
||||||
@anchor GLFW_MOUSE_PASSTHROUGH_hint
|
@anchor GLFW_MOUSE_PASSTHROUGH_hint
|
||||||
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
|
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
|
||||||
input, letting any mouse events pass through to whatever window is behind it.
|
input, letting any mouse events pass through to whatever window is behind it.
|
||||||
|
|||||||
@ -1108,6 +1108,11 @@ extern "C" {
|
|||||||
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for
|
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for
|
||||||
* compatibility with earlier versions.
|
* compatibility with earlier versions.
|
||||||
*/
|
*/
|
||||||
|
#define GLFW_THEME 0x0002200E
|
||||||
|
/*! @brief windows specific
|
||||||
|
*
|
||||||
|
* Allows specifying whether light or dark theme should be used.
|
||||||
|
*/
|
||||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||||
/*! @brief macOS specific
|
/*! @brief macOS specific
|
||||||
* [window hint](@ref GLFW_COCOA_FRAME_NAME_hint).
|
* [window hint](@ref GLFW_COCOA_FRAME_NAME_hint).
|
||||||
@ -1182,6 +1187,10 @@ extern "C" {
|
|||||||
|
|
||||||
#define GLFW_ANY_POSITION 0x80000000
|
#define GLFW_ANY_POSITION 0x80000000
|
||||||
|
|
||||||
|
#define GLFW_THEME_AUTO 0x00000000
|
||||||
|
#define GLFW_THEME_DARK 0x00000001
|
||||||
|
#define GLFW_THEME_LIGHT 0x00000002
|
||||||
|
|
||||||
/*! @defgroup shapes Standard cursor shapes
|
/*! @defgroup shapes Standard cursor shapes
|
||||||
* @brief Standard system cursor shapes.
|
* @brief Standard system cursor shapes.
|
||||||
*
|
*
|
||||||
@ -3480,6 +3489,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
|
GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
|
||||||
|
|
||||||
|
GLFWAPI int glfwIsWindowLightTheme(GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Retrieves the size of the content area of the specified window.
|
/*! @brief Retrieves the size of the content area of the specified window.
|
||||||
*
|
*
|
||||||
* This function retrieves the size, in screen coordinates, of the content area
|
* This function retrieves the size, in screen coordinates, of the content area
|
||||||
|
|||||||
107
premake5.lua
Normal file
107
premake5.lua
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
project "GLFW"
|
||||||
|
kind "StaticLib"
|
||||||
|
language "C"
|
||||||
|
|
||||||
|
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
|
||||||
|
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
|
||||||
|
|
||||||
|
files
|
||||||
|
{
|
||||||
|
"include/GLFW/glfw3.h",
|
||||||
|
"include/GLFW/glfw3native.h",
|
||||||
|
"src/glfw_config.h",
|
||||||
|
"src/context.c",
|
||||||
|
"src/init.c",
|
||||||
|
"src/input.c",
|
||||||
|
"src/monitor.c",
|
||||||
|
|
||||||
|
"src/null_init.c",
|
||||||
|
"src/null_joystick.c",
|
||||||
|
"src/null_monitor.c",
|
||||||
|
"src/null_window.c",
|
||||||
|
|
||||||
|
"src/platform.c",
|
||||||
|
"src/vulkan.c",
|
||||||
|
"src/window.c"
|
||||||
|
}
|
||||||
|
filter "system:linux"
|
||||||
|
pic "On"
|
||||||
|
|
||||||
|
systemversion "latest"
|
||||||
|
staticruntime "On"
|
||||||
|
|
||||||
|
files
|
||||||
|
{
|
||||||
|
"src/x11_init.c",
|
||||||
|
"src/x11_monitor.c",
|
||||||
|
"src/x11_window.c",
|
||||||
|
"src/xkb_unicode.c",
|
||||||
|
"src/posix_module.c",
|
||||||
|
"src/posix_time.c",
|
||||||
|
"src/posix_thread.c",
|
||||||
|
"src/posix_module.c",
|
||||||
|
"src/posix_poll.c",
|
||||||
|
"src/glx_context.c",
|
||||||
|
"src/egl_context.c",
|
||||||
|
"src/osmesa_context.c",
|
||||||
|
"src/linux_joystick.c"
|
||||||
|
}
|
||||||
|
|
||||||
|
defines
|
||||||
|
{
|
||||||
|
"_GLFW_X11"
|
||||||
|
}
|
||||||
|
|
||||||
|
filter "system:macosx"
|
||||||
|
pic "On"
|
||||||
|
|
||||||
|
files
|
||||||
|
{
|
||||||
|
"src/cocoa_init.m",
|
||||||
|
"src/cocoa_monitor.m",
|
||||||
|
"src/cocoa_window.m",
|
||||||
|
"src/cocoa_joystick.m",
|
||||||
|
"src/cocoa_time.c",
|
||||||
|
"src/nsgl_context.m",
|
||||||
|
"src/posix_thread.c",
|
||||||
|
"src/posix_module.c",
|
||||||
|
"src/osmesa_context.c",
|
||||||
|
"src/egl_context.c"
|
||||||
|
}
|
||||||
|
|
||||||
|
defines
|
||||||
|
{
|
||||||
|
"_GLFW_COCOA"
|
||||||
|
}
|
||||||
|
|
||||||
|
filter "system:windows"
|
||||||
|
systemversion "latest"
|
||||||
|
staticruntime "On"
|
||||||
|
|
||||||
|
files
|
||||||
|
{
|
||||||
|
"src/win32_init.c",
|
||||||
|
"src/win32_joystick.c",
|
||||||
|
"src/win32_module.c",
|
||||||
|
"src/win32_monitor.c",
|
||||||
|
"src/win32_time.c",
|
||||||
|
"src/win32_thread.c",
|
||||||
|
"src/win32_window.c",
|
||||||
|
"src/wgl_context.c",
|
||||||
|
"src/egl_context.c",
|
||||||
|
"src/osmesa_context.c"
|
||||||
|
}
|
||||||
|
|
||||||
|
defines
|
||||||
|
{
|
||||||
|
"_GLFW_WIN32",
|
||||||
|
"_CRT_SECURE_NO_WARNINGS"
|
||||||
|
}
|
||||||
|
|
||||||
|
filter "configurations:Debug"
|
||||||
|
runtime "Debug"
|
||||||
|
symbols "on"
|
||||||
|
|
||||||
|
filter "configurations:Release"
|
||||||
|
runtime "Release"
|
||||||
|
optimize "on"
|
||||||
@ -415,6 +415,7 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool mousePassthrough;
|
GLFWbool mousePassthrough;
|
||||||
GLFWbool scaleToMonitor;
|
GLFWbool scaleToMonitor;
|
||||||
GLFWbool scaleFramebuffer;
|
GLFWbool scaleFramebuffer;
|
||||||
|
int theme;
|
||||||
struct {
|
struct {
|
||||||
char frameName[256];
|
char frameName[256];
|
||||||
} ns;
|
} ns;
|
||||||
@ -539,6 +540,7 @@ struct _GLFWwindow
|
|||||||
GLFWbool focusOnShow;
|
GLFWbool focusOnShow;
|
||||||
GLFWbool mousePassthrough;
|
GLFWbool mousePassthrough;
|
||||||
GLFWbool shouldClose;
|
GLFWbool shouldClose;
|
||||||
|
GLFWbool isLightTheme;
|
||||||
void* userPointer;
|
void* userPointer;
|
||||||
GLFWbool doublebuffer;
|
GLFWbool doublebuffer;
|
||||||
GLFWvidmode videoMode;
|
GLFWvidmode videoMode;
|
||||||
|
|||||||
@ -145,6 +145,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||||
|
_glfw.win32.dwmapi.DwmSetWindowAttribute = (PFN_DwmSetWindowAttribute)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmSetWindowAttribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
||||||
@ -563,6 +565,14 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwSetWindowTheme(BOOL dark, HWND hwnd)
|
||||||
|
{
|
||||||
|
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||||
|
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||||
|
#endif
|
||||||
|
_glfw.win32.dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark, sizeof(dark));
|
||||||
|
}
|
||||||
|
|
||||||
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
|
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
|
||||||
// application having a correct embedded manifest
|
// application having a correct embedded manifest
|
||||||
//
|
//
|
||||||
|
|||||||
@ -241,8 +241,9 @@ typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
|||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
typedef HRESULT (WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD);
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
@ -430,6 +431,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
PFN_DwmGetColorizationColor GetColorizationColor;
|
PFN_DwmGetColorizationColor GetColorizationColor;
|
||||||
|
PFN_DwmSetWindowAttribute DwmSetWindowAttribute;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -476,6 +478,7 @@ BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
|||||||
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
||||||
void _glfwInputErrorWin32(int error, const char* description);
|
void _glfwInputErrorWin32(int error, const char* description);
|
||||||
void _glfwUpdateKeyNamesWin32(void);
|
void _glfwUpdateKeyNamesWin32(void);
|
||||||
|
void _glfwSetWindowTheme(BOOL dark, HWND hwnd);
|
||||||
|
|
||||||
void _glfwPollMonitorsWin32(void);
|
void _glfwPollMonitorsWin32(void);
|
||||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
|
|||||||
@ -1392,6 +1392,36 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
_glfw.win32.instance,
|
_glfw.win32.instance,
|
||||||
(LPVOID) wndconfig);
|
(LPVOID) wndconfig);
|
||||||
|
|
||||||
|
BOOL should_use_light_mode;
|
||||||
|
if (wndconfig->theme == GLFW_THEME_AUTO)
|
||||||
|
{
|
||||||
|
BOOL success = FALSE;
|
||||||
|
HKEY hRootKey = HKEY_CURRENT_USER;
|
||||||
|
const wchar_t* lpSubKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||||
|
const wchar_t* lpValueName = L"AppsUseLightTheme";
|
||||||
|
DWORD result;
|
||||||
|
{
|
||||||
|
HKEY hKey = 0;
|
||||||
|
if (RegOpenKeyExW(hRootKey, lpSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DWORD dwBufferSize = sizeof(DWORD);
|
||||||
|
DWORD dwData = 0;
|
||||||
|
if (RegQueryValueExW(hKey, lpValueName, 0, NULL, (LPBYTE)(&dwData), &dwBufferSize) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
result = dwData;
|
||||||
|
success = TRUE;
|
||||||
|
}
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
should_use_light_mode = success && result != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
should_use_light_mode = wndconfig->theme == GLFW_THEME_LIGHT;
|
||||||
|
|
||||||
|
_glfwSetWindowTheme(!should_use_light_mode, window->win32.handle);
|
||||||
|
window->isLightTheme = should_use_light_mode ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
|
||||||
_glfw_free(wideTitle);
|
_glfw_free(wideTitle);
|
||||||
|
|
||||||
if (!window->win32.handle)
|
if (!window->win32.handle)
|
||||||
|
|||||||
11
src/window.c
11
src/window.c
@ -388,6 +388,8 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_SCALE_FRAMEBUFFER:
|
case GLFW_SCALE_FRAMEBUFFER:
|
||||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||||
_glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
case GLFW_THEME:
|
||||||
|
_glfw.hints.window.theme = value;
|
||||||
return;
|
return;
|
||||||
case GLFW_CENTER_CURSOR:
|
case GLFW_CENTER_CURSOR:
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
@ -607,6 +609,15 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
|
|||||||
_glfw.platform.setWindowPos(window, xpos, ypos);
|
_glfw.platform.setWindowPos(window, xpos, ypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwIsWindowLightTheme(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*)handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||||
|
return window->isLightTheme;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
|
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
|
||||||
{
|
{
|
||||||
if (width)
|
if (width)
|
||||||
|
|||||||
@ -217,62 +217,62 @@ struct libdecor_configuration;
|
|||||||
|
|
||||||
enum libdecor_error
|
enum libdecor_error
|
||||||
{
|
{
|
||||||
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
|
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
|
||||||
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
|
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum libdecor_window_state
|
enum libdecor_window_state
|
||||||
{
|
{
|
||||||
LIBDECOR_WINDOW_STATE_NONE = 0,
|
LIBDECOR_WINDOW_STATE_NONE = 0,
|
||||||
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
|
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
|
||||||
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
|
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
|
||||||
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
|
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
|
||||||
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
|
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
|
||||||
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
|
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
|
||||||
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
|
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
|
||||||
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
|
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
|
||||||
};
|
};
|
||||||
|
|
||||||
enum libdecor_capabilities
|
enum libdecor_capabilities
|
||||||
{
|
{
|
||||||
LIBDECOR_ACTION_MOVE = 1,
|
LIBDECOR_ACTION_MOVE = 1,
|
||||||
LIBDECOR_ACTION_RESIZE = 2,
|
LIBDECOR_ACTION_RESIZE = 2,
|
||||||
LIBDECOR_ACTION_MINIMIZE = 4,
|
LIBDECOR_ACTION_MINIMIZE = 4,
|
||||||
LIBDECOR_ACTION_FULLSCREEN = 8,
|
LIBDECOR_ACTION_FULLSCREEN = 8,
|
||||||
LIBDECOR_ACTION_CLOSE = 16
|
LIBDECOR_ACTION_CLOSE = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
struct libdecor_interface
|
struct libdecor_interface
|
||||||
{
|
{
|
||||||
void (* error)(struct libdecor*,enum libdecor_error,const char*);
|
void (* error)(struct libdecor*,enum libdecor_error,const char*);
|
||||||
void (* reserved0)(void);
|
void (* reserved0)(void);
|
||||||
void (* reserved1)(void);
|
void (* reserved1)(void);
|
||||||
void (* reserved2)(void);
|
void (* reserved2)(void);
|
||||||
void (* reserved3)(void);
|
void (* reserved3)(void);
|
||||||
void (* reserved4)(void);
|
void (* reserved4)(void);
|
||||||
void (* reserved5)(void);
|
void (* reserved5)(void);
|
||||||
void (* reserved6)(void);
|
void (* reserved6)(void);
|
||||||
void (* reserved7)(void);
|
void (* reserved7)(void);
|
||||||
void (* reserved8)(void);
|
void (* reserved8)(void);
|
||||||
void (* reserved9)(void);
|
void (* reserved9)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct libdecor_frame_interface
|
struct libdecor_frame_interface
|
||||||
{
|
{
|
||||||
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
|
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
|
||||||
void (* close)(struct libdecor_frame*,void*);
|
void (* close)(struct libdecor_frame*,void*);
|
||||||
void (* commit)(struct libdecor_frame*,void*);
|
void (* commit)(struct libdecor_frame*,void*);
|
||||||
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
|
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
|
||||||
void (* reserved0)(void);
|
void (* reserved0)(void);
|
||||||
void (* reserved1)(void);
|
void (* reserved1)(void);
|
||||||
void (* reserved2)(void);
|
void (* reserved2)(void);
|
||||||
void (* reserved3)(void);
|
void (* reserved3)(void);
|
||||||
void (* reserved4)(void);
|
void (* reserved4)(void);
|
||||||
void (* reserved5)(void);
|
void (* reserved5)(void);
|
||||||
void (* reserved6)(void);
|
void (* reserved6)(void);
|
||||||
void (* reserved7)(void);
|
void (* reserved7)(void);
|
||||||
void (* reserved8)(void);
|
void (* reserved8)(void);
|
||||||
void (* reserved9)(void);
|
void (* reserved9)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
|
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
|
||||||
@ -413,6 +413,8 @@ typedef struct _GLFWwindowWayland
|
|||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
_GLFWfallbackEdgeWayland top, left, right, bottom;
|
_GLFWfallbackEdgeWayland top, left, right, bottom;
|
||||||
struct wl_surface* focus;
|
struct wl_surface* focus;
|
||||||
|
wl_fixed_t pointerX, pointerY;
|
||||||
|
const char* cursorName;
|
||||||
} fallback;
|
} fallback;
|
||||||
} _GLFWwindowWayland;
|
} _GLFWwindowWayland;
|
||||||
|
|
||||||
@ -454,7 +456,6 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_cursor_theme* cursorTheme;
|
struct wl_cursor_theme* cursorTheme;
|
||||||
struct wl_cursor_theme* cursorThemeHiDPI;
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
const char* cursorPreviousName;
|
|
||||||
int cursorTimerfd;
|
int cursorTimerfd;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
uint32_t pointerEnterSerial;
|
uint32_t pointerEnterSerial;
|
||||||
|
|||||||
333
src/wl_window.c
333
src/wl_window.c
@ -275,6 +275,146 @@ static void destroyFallbackDecorations(_GLFWwindow* window)
|
|||||||
destroyFallbackEdge(&window->wl.fallback.bottom);
|
destroyFallbackEdge(&window->wl.fallback.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void updateFallbackDecorationCursor(_GLFWwindow* window,
|
||||||
|
wl_fixed_t sx,
|
||||||
|
wl_fixed_t sy)
|
||||||
|
{
|
||||||
|
window->wl.fallback.pointerX = sx;
|
||||||
|
window->wl.fallback.pointerY = sy;
|
||||||
|
|
||||||
|
const double xpos = wl_fixed_to_double(sx);
|
||||||
|
const double ypos = wl_fixed_to_double(sy);
|
||||||
|
const char* cursorName = "left_ptr";
|
||||||
|
|
||||||
|
if (window->resizable)
|
||||||
|
{
|
||||||
|
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
cursorName = "n-resize";
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
cursorName = "nw-resize";
|
||||||
|
else
|
||||||
|
cursorName = "w-resize";
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
cursorName = "ne-resize";
|
||||||
|
else
|
||||||
|
cursorName = "e-resize";
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||||
|
{
|
||||||
|
if (xpos < GLFW_BORDER_SIZE)
|
||||||
|
cursorName = "sw-resize";
|
||||||
|
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
||||||
|
cursorName = "se-resize";
|
||||||
|
else
|
||||||
|
cursorName = "s-resize";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->wl.fallback.cursorName != cursorName)
|
||||||
|
{
|
||||||
|
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||||
|
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
|
if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||||
|
{
|
||||||
|
// We only support up to scale=2 for now, since libwayland-cursor
|
||||||
|
// requires us to load a different theme for each size.
|
||||||
|
scale = 2;
|
||||||
|
theme = _glfw.wl.cursorThemeHiDPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName);
|
||||||
|
if (!cursor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: handle animated cursors too.
|
||||||
|
struct wl_cursor_image* image = cursor->images[0];
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);
|
||||||
|
if (!buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,
|
||||||
|
surface,
|
||||||
|
image->hotspot_x / scale,
|
||||||
|
image->hotspot_y / scale);
|
||||||
|
wl_surface_set_buffer_scale(surface, scale);
|
||||||
|
wl_surface_attach(surface, buffer, 0, 0);
|
||||||
|
wl_surface_damage(surface, 0, 0, image->width, image->height);
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
|
||||||
|
window->wl.fallback.cursorName = cursorName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleFallbackDecorationButton(_GLFWwindow* window,
|
||||||
|
uint32_t serial,
|
||||||
|
uint32_t button)
|
||||||
|
{
|
||||||
|
const double xpos = wl_fixed_to_double(window->wl.fallback.pointerX);
|
||||||
|
const double ypos = wl_fixed_to_double(window->wl.fallback.pointerY);
|
||||||
|
|
||||||
|
if (button == BTN_LEFT)
|
||||||
|
{
|
||||||
|
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||||
|
|
||||||
|
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||||
|
else
|
||||||
|
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||||
|
else
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||||
|
{
|
||||||
|
if (ypos < GLFW_BORDER_SIZE)
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||||
|
else
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||||
|
}
|
||||||
|
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||||
|
{
|
||||||
|
if (xpos < GLFW_BORDER_SIZE)
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||||
|
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
|
||||||
|
else
|
||||||
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
||||||
|
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, serial, edges);
|
||||||
|
}
|
||||||
|
else if (button == BTN_RIGHT)
|
||||||
|
{
|
||||||
|
if (window->wl.xdg.toplevel)
|
||||||
|
{
|
||||||
|
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||||
|
_glfw.wl.seat, serial,
|
||||||
|
window->wl.cursorPosX,
|
||||||
|
window->wl.cursorPosY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void xdgDecorationHandleConfigure(void* userData,
|
static void xdgDecorationHandleConfigure(void* userData,
|
||||||
struct zxdg_toplevel_decoration_v1* decoration,
|
struct zxdg_toplevel_decoration_v1* decoration,
|
||||||
uint32_t mode)
|
uint32_t mode)
|
||||||
@ -1417,7 +1557,6 @@ static void pointerHandleLeave(void* userData,
|
|||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
|
||||||
|
|
||||||
if (window->wl.hovered)
|
if (window->wl.hovered)
|
||||||
{
|
{
|
||||||
@ -1427,7 +1566,10 @@ static void pointerHandleLeave(void* userData,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (window->wl.fallback.decorations)
|
if (window->wl.fallback.decorations)
|
||||||
|
{
|
||||||
window->wl.fallback.focus = NULL;
|
window->wl.fallback.focus = NULL;
|
||||||
|
window->wl.fallback.cursorName = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,92 +1586,16 @@ static void pointerHandleMotion(void* userData,
|
|||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const double xpos = wl_fixed_to_double(sx);
|
|
||||||
const double ypos = wl_fixed_to_double(sy);
|
|
||||||
window->wl.cursorPosX = xpos;
|
|
||||||
window->wl.cursorPosY = ypos;
|
|
||||||
|
|
||||||
if (window->wl.hovered)
|
if (window->wl.hovered)
|
||||||
{
|
{
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||||
_glfwInputCursorPos(window, xpos, ypos);
|
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||||
return;
|
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (window->wl.fallback.decorations)
|
|
||||||
{
|
{
|
||||||
const char* cursorName = "left_ptr";
|
if (window->wl.fallback.decorations)
|
||||||
|
updateFallbackDecorationCursor(window, sx, sy);
|
||||||
if (window->resizable)
|
|
||||||
{
|
|
||||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
|
||||||
{
|
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
|
||||||
cursorName = "n-resize";
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
|
||||||
{
|
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
|
||||||
cursorName = "nw-resize";
|
|
||||||
else
|
|
||||||
cursorName = "w-resize";
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
|
||||||
{
|
|
||||||
if (ypos < GLFW_BORDER_SIZE)
|
|
||||||
cursorName = "ne-resize";
|
|
||||||
else
|
|
||||||
cursorName = "e-resize";
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
|
||||||
{
|
|
||||||
if (xpos < GLFW_BORDER_SIZE)
|
|
||||||
cursorName = "sw-resize";
|
|
||||||
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
|
||||||
cursorName = "se-resize";
|
|
||||||
else
|
|
||||||
cursorName = "s-resize";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wl.cursorPreviousName != cursorName)
|
|
||||||
{
|
|
||||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
|
||||||
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
|
||||||
int scale = 1;
|
|
||||||
|
|
||||||
if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
|
||||||
{
|
|
||||||
// We only support up to scale=2 for now, since libwayland-cursor
|
|
||||||
// requires us to load a different theme for each size.
|
|
||||||
scale = 2;
|
|
||||||
theme = _glfw.wl.cursorThemeHiDPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName);
|
|
||||||
if (!cursor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// TODO: handle animated cursors too.
|
|
||||||
struct wl_cursor_image* image = cursor->images[0];
|
|
||||||
if (!image)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);
|
|
||||||
if (!buffer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,
|
|
||||||
surface,
|
|
||||||
image->hotspot_x / scale,
|
|
||||||
image->hotspot_y / scale);
|
|
||||||
wl_surface_set_buffer_scale(surface, scale);
|
|
||||||
wl_surface_attach(surface, buffer, 0, 0);
|
|
||||||
wl_surface_damage(surface, 0, 0, image->width, image->height);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
|
|
||||||
_glfw.wl.cursorPreviousName = cursorName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1552,62 +1618,11 @@ static void pointerHandleButton(void* userData,
|
|||||||
button - BTN_LEFT,
|
button - BTN_LEFT,
|
||||||
state == WL_POINTER_BUTTON_STATE_PRESSED,
|
state == WL_POINTER_BUTTON_STATE_PRESSED,
|
||||||
_glfw.wl.xkb.modifiers);
|
_glfw.wl.xkb.modifiers);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (window->wl.fallback.decorations)
|
|
||||||
{
|
{
|
||||||
if (button == BTN_LEFT)
|
if (window->wl.fallback.decorations)
|
||||||
{
|
handleFallbackDecorationButton(window, serial, button);
|
||||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
|
||||||
|
|
||||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
|
||||||
{
|
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
|
||||||
else
|
|
||||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
|
||||||
{
|
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
|
||||||
else
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
|
||||||
{
|
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
|
||||||
else
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
|
||||||
}
|
|
||||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
|
||||||
{
|
|
||||||
if (window->wl.cursorPosX < GLFW_BORDER_SIZE)
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
|
||||||
else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
|
|
||||||
else
|
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
|
||||||
{
|
|
||||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
|
||||||
serial, edges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (button == BTN_RIGHT)
|
|
||||||
{
|
|
||||||
if (window->wl.xdg.toplevel)
|
|
||||||
{
|
|
||||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
|
||||||
_glfw.wl.seat, serial,
|
|
||||||
window->wl.cursorPosX,
|
|
||||||
window->wl.cursorPosY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,11 +1636,14 @@ static void pointerHandleAxis(void* userData,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
if (window->wl.hovered)
|
||||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
{
|
||||||
_glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);
|
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
||||||
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||||
_glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);
|
_glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);
|
||||||
|
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||||
|
_glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_pointer_listener pointerListener =
|
static const struct wl_pointer_listener pointerListener =
|
||||||
@ -1760,24 +1778,6 @@ static void keyboardHandleLeave(void* userData,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Handle any key repeats up to this point. We don't poll as this should be infrequent.
|
|
||||||
uint64_t repeats;
|
|
||||||
if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8)
|
|
||||||
{
|
|
||||||
if(_glfw.wl.keyboardFocus)
|
|
||||||
{
|
|
||||||
for (uint64_t i = 0; i < repeats; i++)
|
|
||||||
{
|
|
||||||
_glfwInputKey(_glfw.wl.keyboardFocus,
|
|
||||||
translateKey(_glfw.wl.keyRepeatScancode),
|
|
||||||
_glfw.wl.keyRepeatScancode,
|
|
||||||
GLFW_PRESS,
|
|
||||||
_glfw.wl.xkb.modifiers);
|
|
||||||
inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct itimerspec timer = {0};
|
struct itimerspec timer = {0};
|
||||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
@ -1820,11 +1820,12 @@ static void keyboardHandleKey(void* userData,
|
|||||||
|
|
||||||
timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;
|
timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;
|
||||||
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
||||||
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
}
|
}
|
||||||
|
} else if (scancode == _glfw.wl.keyRepeatScancode) {
|
||||||
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
|
||||||
|
|
||||||
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
||||||
|
|
||||||
if (action == GLFW_PRESS)
|
if (action == GLFW_PRESS)
|
||||||
@ -2207,12 +2208,12 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
|||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
|
|
||||||
if (window == _glfw.wl.keyboardFocus)
|
if (window == _glfw.wl.keyboardFocus)
|
||||||
{
|
{
|
||||||
struct itimerspec timer = {0};
|
struct itimerspec timer = {0};
|
||||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
_glfw.wl.keyboardFocus = NULL;
|
_glfw.wl.keyboardFocus = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->wl.fractionalScale)
|
if (window->wl.fractionalScale)
|
||||||
wp_fractional_scale_v1_destroy(window->wl.fractionalScale);
|
wp_fractional_scale_v1_destroy(window->wl.fractionalScale);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user