mirror of
https://github.com/glfw/glfw.git
synced 2024-11-27 12:32:00 +00:00
Merge branch 'glfw:master' into drag-window-dev
This commit is contained in:
commit
673f5dd4fd
@ -82,6 +82,7 @@ video tutorials.
|
|||||||
- Jonathan Hale
|
- Jonathan Hale
|
||||||
- hdf89shfdfs
|
- hdf89shfdfs
|
||||||
- Sylvain Hellegouarch
|
- Sylvain Hellegouarch
|
||||||
|
- Björn Hempel
|
||||||
- Matthew Henry
|
- Matthew Henry
|
||||||
- heromyth
|
- heromyth
|
||||||
- Lucas Hinderberger
|
- Lucas Hinderberger
|
||||||
@ -186,6 +187,7 @@ video tutorials.
|
|||||||
- Philip Rideout
|
- Philip Rideout
|
||||||
- Eddie Ringle
|
- Eddie Ringle
|
||||||
- Max Risuhin
|
- Max Risuhin
|
||||||
|
- Joe Roback
|
||||||
- Jorge Rodriguez
|
- Jorge Rodriguez
|
||||||
- Jari Ronkainen
|
- Jari Ronkainen
|
||||||
- Luca Rood
|
- Luca Rood
|
||||||
|
@ -373,8 +373,10 @@ information on what to include when reporting a bug.
|
|||||||
wlroots compositors (#1268)
|
wlroots compositors (#1268)
|
||||||
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
|
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
|
||||||
decorations
|
decorations
|
||||||
|
- [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450)
|
||||||
- [POSIX] Removed use of deprecated function `gettimeofday`
|
- [POSIX] Removed use of deprecated function `gettimeofday`
|
||||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||||
|
- [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043)
|
||||||
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
||||||
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
||||||
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
||||||
|
@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure this device supports the events expected of a joystick
|
// Ensure this device supports the events expected of a joystick
|
||||||
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
if (!isBitSet(EV_ABS, evBits))
|
||||||
{
|
{
|
||||||
close(linjs.fd);
|
close(linjs.fd);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
@ -335,6 +335,38 @@ static void createKeyTables(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLFWbool loadCursorTheme(void)
|
||||||
|
{
|
||||||
|
int cursorSize = 32;
|
||||||
|
|
||||||
|
const char* sizeString = getenv("XCURSOR_SIZE");
|
||||||
|
if (sizeString)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
const long cursorSizeLong = strtol(sizeString, NULL, 10);
|
||||||
|
if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX)
|
||||||
|
cursorSize = (int) cursorSizeLong;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* themeName = getenv("XCURSOR_THEME");
|
||||||
|
|
||||||
|
_glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm);
|
||||||
|
if (!_glfw.wl.cursorTheme)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to load default cursor theme");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this happens to be NULL, we just fallback to the scale=1 version.
|
||||||
|
_glfw.wl.cursorThemeHiDPI =
|
||||||
|
wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm);
|
||||||
|
|
||||||
|
_glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -472,14 +504,8 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
|
|
||||||
int _glfwInitWayland(void)
|
int _glfwInitWayland(void)
|
||||||
{
|
{
|
||||||
const char* cursorTheme;
|
|
||||||
const char* cursorSizeStr;
|
|
||||||
char* cursorSizeEnd;
|
|
||||||
long cursorSizeLong;
|
|
||||||
int cursorSize;
|
|
||||||
|
|
||||||
// These must be set before any failure checks
|
// These must be set before any failure checks
|
||||||
_glfw.wl.timerfd = -1;
|
_glfw.wl.keyRepeatTimerfd = -1;
|
||||||
_glfw.wl.cursorTimerfd = -1;
|
_glfw.wl.cursorTimerfd = -1;
|
||||||
|
|
||||||
_glfw.wl.client.display_flush = (PFN_wl_display_flush)
|
_glfw.wl.client.display_flush = (PFN_wl_display_flush)
|
||||||
@ -640,7 +666,10 @@ int _glfwInitWayland(void)
|
|||||||
|
|
||||||
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||||
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
||||||
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
{
|
||||||
|
_glfw.wl.keyRepeatTimerfd =
|
||||||
|
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!_glfw.wl.wmBase)
|
if (!_glfw.wl.wmBase)
|
||||||
@ -650,34 +679,16 @@ int _glfwInitWayland(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.wl.pointer && _glfw.wl.shm)
|
if (!_glfw.wl.shm)
|
||||||
{
|
{
|
||||||
cursorTheme = getenv("XCURSOR_THEME");
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
cursorSizeStr = getenv("XCURSOR_SIZE");
|
"Wayland: Failed to find wl_shm in your compositor");
|
||||||
cursorSize = 32;
|
return GLFW_FALSE;
|
||||||
if (cursorSizeStr)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
|
|
||||||
if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
|
|
||||||
cursorSize = (int)cursorSizeLong;
|
|
||||||
}
|
|
||||||
_glfw.wl.cursorTheme =
|
|
||||||
wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
|
|
||||||
if (!_glfw.wl.cursorTheme)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Wayland: Failed to load default cursor theme");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
// If this happens to be NULL, we just fallback to the scale=1 version.
|
|
||||||
_glfw.wl.cursorThemeHiDPI =
|
|
||||||
wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
|
|
||||||
_glfw.wl.cursorSurface =
|
|
||||||
wl_compositor_create_surface(_glfw.wl.compositor);
|
|
||||||
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!loadCursorTheme())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
|
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
|
||||||
{
|
{
|
||||||
_glfw.wl.dataDevice =
|
_glfw.wl.dataDevice =
|
||||||
@ -773,8 +784,8 @@ void _glfwTerminateWayland(void)
|
|||||||
wl_display_disconnect(_glfw.wl.display);
|
wl_display_disconnect(_glfw.wl.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.wl.timerfd >= 0)
|
if (_glfw.wl.keyRepeatTimerfd >= 0)
|
||||||
close(_glfw.wl.timerfd);
|
close(_glfw.wl.keyRepeatTimerfd);
|
||||||
if (_glfw.wl.cursorTimerfd >= 0)
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
close(_glfw.wl.cursorTimerfd);
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
|
@ -322,12 +322,12 @@ typedef struct _GLFWlibraryWayland
|
|||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
uint32_t pointerEnterSerial;
|
uint32_t pointerEnterSerial;
|
||||||
|
|
||||||
int32_t keyboardRepeatRate;
|
int keyRepeatTimerfd;
|
||||||
int32_t keyboardRepeatDelay;
|
int32_t keyRepeatRate;
|
||||||
int keyboardLastKey;
|
int32_t keyRepeatDelay;
|
||||||
int keyboardLastScancode;
|
int keyRepeatScancode;
|
||||||
|
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
int timerfd;
|
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char keynames[GLFW_KEY_LAST + 1][5];
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
@ -516,7 +516,6 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
|||||||
|
|
||||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||||
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
|
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
|
||||||
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode);
|
|
||||||
|
|
||||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||||
|
166
src/wl_window.c
166
src/wl_window.c
@ -142,11 +142,8 @@ static int createAnonymousFile(off_t size)
|
|||||||
|
|
||||||
static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||||
{
|
{
|
||||||
struct wl_shm_pool* pool;
|
const int stride = image->width * 4;
|
||||||
struct wl_buffer* buffer;
|
const int length = image->width * image->height * 4;
|
||||||
int stride = image->width * 4;
|
|
||||||
int length = image->width * image->height * 4;
|
|
||||||
void* data;
|
|
||||||
|
|
||||||
const int fd = createAnonymousFile(length);
|
const int fd = createAnonymousFile(length);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -157,7 +154,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
void* data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (data == MAP_FAILED)
|
if (data == MAP_FAILED)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -166,9 +163,10 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
|
struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
unsigned char* source = (unsigned char*) image->pixels;
|
unsigned char* source = (unsigned char*) image->pixels;
|
||||||
unsigned char* target = data;
|
unsigned char* target = data;
|
||||||
for (int i = 0; i < image->width * image->height; i++, source += 4)
|
for (int i = 0; i < image->width * image->height; i++, source += 4)
|
||||||
@ -181,7 +179,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
*target++ = (unsigned char) alpha;
|
*target++ = (unsigned char) alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer =
|
struct wl_buffer* buffer =
|
||||||
wl_shm_pool_create_buffer(pool, 0,
|
wl_shm_pool_create_buffer(pool, 0,
|
||||||
image->width,
|
image->width,
|
||||||
image->height,
|
image->height,
|
||||||
@ -743,7 +741,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window,
|
|||||||
static void setCursorImage(_GLFWwindow* window,
|
static void setCursorImage(_GLFWwindow* window,
|
||||||
_GLFWcursorWayland* cursorWayland)
|
_GLFWcursorWayland* cursorWayland)
|
||||||
{
|
{
|
||||||
struct itimerspec timer = {};
|
struct itimerspec timer = {0};
|
||||||
struct wl_cursor* wlCursor = cursorWayland->cursor;
|
struct wl_cursor* wlCursor = cursorWayland->cursor;
|
||||||
struct wl_cursor_image* image;
|
struct wl_cursor_image* image;
|
||||||
struct wl_buffer* buffer;
|
struct wl_buffer* buffer;
|
||||||
@ -821,13 +819,59 @@ static GLFWbool flushDisplay(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int translateKey(uint32_t scancode)
|
||||||
|
{
|
||||||
|
if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
||||||
|
return _glfw.wl.keycodes[scancode];
|
||||||
|
|
||||||
|
return GLFW_KEY_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||||
|
{
|
||||||
|
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
||||||
|
return sym;
|
||||||
|
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
|
||||||
|
!= XKB_COMPOSE_FEED_ACCEPTED)
|
||||||
|
return sym;
|
||||||
|
switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))
|
||||||
|
{
|
||||||
|
case XKB_COMPOSE_COMPOSED:
|
||||||
|
return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);
|
||||||
|
case XKB_COMPOSE_COMPOSING:
|
||||||
|
case XKB_COMPOSE_CANCELLED:
|
||||||
|
return XKB_KEY_NoSymbol;
|
||||||
|
case XKB_COMPOSE_NOTHING:
|
||||||
|
default:
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inputText(_GLFWwindow* window, uint32_t scancode)
|
||||||
|
{
|
||||||
|
const xkb_keysym_t* keysyms;
|
||||||
|
const xkb_keycode_t keycode = scancode + 8;
|
||||||
|
|
||||||
|
if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)
|
||||||
|
{
|
||||||
|
const xkb_keysym_t keysym = composeSymbol(keysyms[0]);
|
||||||
|
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||||
|
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||||
|
{
|
||||||
|
const int mods = _glfw.wl.xkb.modifiers;
|
||||||
|
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
||||||
|
_glfwInputChar(window, codepoint, mods, plain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handleEvents(double* timeout)
|
static void handleEvents(double* timeout)
|
||||||
{
|
{
|
||||||
GLFWbool event = GLFW_FALSE;
|
GLFWbool event = GLFW_FALSE;
|
||||||
struct pollfd fds[] =
|
struct pollfd fds[] =
|
||||||
{
|
{
|
||||||
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||||
{ _glfw.wl.timerfd, POLLIN },
|
{ _glfw.wl.keyRepeatTimerfd, POLLIN },
|
||||||
{ _glfw.wl.cursorTimerfd, POLLIN },
|
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -871,17 +915,16 @@ static void handleEvents(double* timeout)
|
|||||||
{
|
{
|
||||||
uint64_t repeats;
|
uint64_t repeats;
|
||||||
|
|
||||||
if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8)
|
if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8)
|
||||||
{
|
{
|
||||||
for (uint64_t i = 0; i < repeats; i++)
|
for (uint64_t i = 0; i < repeats; i++)
|
||||||
{
|
{
|
||||||
_glfwInputKey(_glfw.wl.keyboardFocus,
|
_glfwInputKey(_glfw.wl.keyboardFocus,
|
||||||
_glfw.wl.keyboardLastKey,
|
translateKey(_glfw.wl.keyRepeatScancode),
|
||||||
_glfw.wl.keyboardLastScancode,
|
_glfw.wl.keyRepeatScancode,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
_glfw.wl.xkb.modifiers);
|
_glfw.wl.xkb.modifiers);
|
||||||
_glfwInputTextWayland(_glfw.wl.keyboardFocus,
|
inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode);
|
||||||
_glfw.wl.keyboardLastScancode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event = GLFW_TRUE;
|
event = GLFW_TRUE;
|
||||||
@ -1044,8 +1087,8 @@ static void pointerHandleLeave(void* userData,
|
|||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
|
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursor(_GLFWwindow* window, const char* name)
|
static void setCursor(_GLFWwindow* window, const char* name)
|
||||||
@ -1116,8 +1159,8 @@ static void pointerHandleMotion(void* userData,
|
|||||||
switch (window->wl.decorations.focus)
|
switch (window->wl.decorations.focus)
|
||||||
{
|
{
|
||||||
case mainWindow:
|
case mainWindow:
|
||||||
_glfwInputCursorPos(window, x, y);
|
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
|
_glfwInputCursorPos(window, x, y);
|
||||||
return;
|
return;
|
||||||
case topDecoration:
|
case topDecoration:
|
||||||
if (y < GLFW_BORDER_SIZE)
|
if (y < GLFW_BORDER_SIZE)
|
||||||
@ -1397,62 +1440,14 @@ static void keyboardHandleLeave(void* userData,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct itimerspec timer = {};
|
struct itimerspec timer = {0};
|
||||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.keyboardFocus = NULL;
|
_glfw.wl.keyboardFocus = NULL;
|
||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int translateKey(uint32_t scancode)
|
|
||||||
{
|
|
||||||
if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
|
||||||
return _glfw.wl.keycodes[scancode];
|
|
||||||
|
|
||||||
return GLFW_KEY_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
|
||||||
{
|
|
||||||
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
|
||||||
return sym;
|
|
||||||
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
|
|
||||||
!= XKB_COMPOSE_FEED_ACCEPTED)
|
|
||||||
return sym;
|
|
||||||
switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))
|
|
||||||
{
|
|
||||||
case XKB_COMPOSE_COMPOSED:
|
|
||||||
return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);
|
|
||||||
case XKB_COMPOSE_COMPOSING:
|
|
||||||
case XKB_COMPOSE_CANCELLED:
|
|
||||||
return XKB_KEY_NoSymbol;
|
|
||||||
case XKB_COMPOSE_NOTHING:
|
|
||||||
default:
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode)
|
|
||||||
{
|
|
||||||
const xkb_keysym_t* keysyms;
|
|
||||||
const xkb_keycode_t keycode = scancode + 8;
|
|
||||||
|
|
||||||
if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)
|
|
||||||
{
|
|
||||||
const xkb_keysym_t keysym = composeSymbol(keysyms[0]);
|
|
||||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
|
||||||
if (codepoint != GLFW_INVALID_CODEPOINT)
|
|
||||||
{
|
|
||||||
const int mods = _glfw.wl.xkb.modifiers;
|
|
||||||
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
|
||||||
_glfwInputChar(window, codepoint, mods, plain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void keyboardHandleKey(void* userData,
|
static void keyboardHandleKey(void* userData,
|
||||||
struct wl_keyboard* keyboard,
|
struct wl_keyboard* keyboard,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
@ -1469,29 +1464,33 @@ static void keyboardHandleKey(void* userData,
|
|||||||
state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
|
||||||
|
|
||||||
struct itimerspec timer = {};
|
struct itimerspec timer = {0};
|
||||||
|
|
||||||
if (action == GLFW_PRESS)
|
if (action == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode);
|
const xkb_keycode_t keycode = scancode + 8;
|
||||||
|
|
||||||
if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0)
|
if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) &&
|
||||||
|
_glfw.wl.keyRepeatRate > 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.keyboardLastKey = key;
|
_glfw.wl.keyRepeatScancode = scancode;
|
||||||
_glfw.wl.keyboardLastScancode = scancode;
|
if (_glfw.wl.keyRepeatRate > 1)
|
||||||
if (_glfw.wl.keyboardRepeatRate > 1)
|
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate;
|
||||||
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
|
|
||||||
else
|
else
|
||||||
timer.it_interval.tv_sec = 1;
|
timer.it_interval.tv_sec = 1;
|
||||||
|
|
||||||
timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000;
|
timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;
|
||||||
timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000;
|
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
|
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
||||||
|
|
||||||
|
if (action == GLFW_PRESS)
|
||||||
|
inputText(window, scancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboardHandleModifiers(void* userData,
|
static void keyboardHandleModifiers(void* userData,
|
||||||
@ -1551,8 +1550,8 @@ static void keyboardHandleRepeatInfo(void* userData,
|
|||||||
if (keyboard != _glfw.wl.keyboard)
|
if (keyboard != _glfw.wl.keyboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfw.wl.keyboardRepeatRate = rate;
|
_glfw.wl.keyRepeatRate = rate;
|
||||||
_glfw.wl.keyboardRepeatDelay = delay;
|
_glfw.wl.keyRepeatDelay = delay;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1843,15 +1842,10 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window == _glfw.wl.pointerFocus)
|
if (window == _glfw.wl.pointerFocus)
|
||||||
{
|
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
|
||||||
}
|
|
||||||
if (window == _glfw.wl.keyboardFocus)
|
if (window == _glfw.wl.keyboardFocus)
|
||||||
{
|
|
||||||
_glfw.wl.keyboardFocus = NULL;
|
_glfw.wl.keyboardFocus = NULL;
|
||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->wl.idleInhibitor)
|
if (window->wl.idleInhibitor)
|
||||||
zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
|
zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
|
||||||
|
@ -642,7 +642,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
glfwMakeContextCurrent(slots[i].window);
|
glfwMakeContextCurrent(slots[i].window);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
glfwSwapInterval(1);
|
glfwSwapBuffers(slots[i].window);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Main loop starting\n");
|
printf("Main loop starting\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user