mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-06 09:15:57 +02:00
On compositors that support compositor key repeat events, use those, for complete robustness. Sadly no actual compositor implements these yet. Otherwise use a timer fd/pipe to queue the repeat events and only dispatch them after events from the compositor are handled. This means release events from the compositor will prevent spurious repeat events. One can, in the worst case lose some repeat events if there is a very large interval between the start of the timer and the next poll, but that is unavoidable and is why repeat events should come from the compositor in the first place. Fixes #9224
110 lines
3.6 KiB
C
Vendored
110 lines
3.6 KiB
C
Vendored
//========================================================================
|
|
// GLFW 3.4
|
|
//------------------------------------------------------------------------
|
|
// Copyright (c) 2014 Kovid Goyal
|
|
//
|
|
// This software is provided 'as-is', without any express or implied
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
// arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would
|
|
// be appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such, and must not
|
|
// be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source
|
|
// distribution.
|
|
//
|
|
//========================================================================
|
|
|
|
#pragma once
|
|
#include "../kitty/monotonic.h"
|
|
#include <poll.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <sys/types.h>
|
|
|
|
#ifdef __has_include
|
|
#if __has_include(<sys/eventfd.h>)
|
|
#define HAS_EVENT_FD
|
|
#include <sys/eventfd.h>
|
|
#endif
|
|
#if __has_include(<sys/timerfd.h>)
|
|
#define HAS_TIMER_FD
|
|
#include <sys/timerfd.h>
|
|
#endif
|
|
#else
|
|
#define HAS_EVENT_FD
|
|
#include <sys/eventfd.h>
|
|
#endif
|
|
|
|
typedef unsigned long long id_type;
|
|
typedef void(*watch_callback_func)(int, int, void*);
|
|
typedef void(*timer_callback_func)(id_type, void*);
|
|
typedef void (* GLFWuserdatafreefun)(id_type, void*);
|
|
|
|
typedef struct {
|
|
int fd, events, enabled, ready;
|
|
watch_callback_func callback;
|
|
void *callback_data;
|
|
GLFWuserdatafreefun free;
|
|
id_type id;
|
|
const char *name;
|
|
} Watch;
|
|
|
|
typedef struct {
|
|
id_type id;
|
|
monotonic_t interval, trigger_at;
|
|
timer_callback_func callback;
|
|
void *callback_data;
|
|
GLFWuserdatafreefun free;
|
|
const char *name;
|
|
bool repeats;
|
|
} Timer;
|
|
|
|
|
|
typedef struct {
|
|
struct pollfd fds[32];
|
|
#ifdef HAS_EVENT_FD
|
|
int wakeupFd;
|
|
#else
|
|
int wakeupFds[2];
|
|
#endif
|
|
#ifdef HAS_TIMER_FD
|
|
int key_repeat_fd;
|
|
#else
|
|
int key_repeat_fds[2];
|
|
#endif
|
|
bool wakeup_data_read, wakeup_fd_ready, key_repeat_fd_ready;
|
|
nfds_t watches_count, timers_count;
|
|
Watch watches[32];
|
|
Timer timers[128];
|
|
} EventLoopData;
|
|
|
|
|
|
void check_for_wakeup_events(EventLoopData *eld);
|
|
id_type addWatch(EventLoopData *eld, const char *name, int fd, int events, int enabled, watch_callback_func cb, void *cb_data);
|
|
void removeWatch(EventLoopData *eld, id_type watch_id);
|
|
void toggleWatch(EventLoopData *eld, id_type watch_id, int enabled);
|
|
id_type addTimer(EventLoopData *eld, const char *name, monotonic_t interval, int enabled, bool repeats, timer_callback_func cb, void *cb_data, GLFWuserdatafreefun free);
|
|
void removeTimer(EventLoopData *eld, id_type timer_id);
|
|
void removeAllTimers(EventLoopData *eld);
|
|
void toggleTimer(EventLoopData *eld, id_type timer_id, int enabled);
|
|
void changeTimerInterval(EventLoopData *eld, id_type timer_id, monotonic_t interval);
|
|
monotonic_t prepareForPoll(EventLoopData *eld, monotonic_t timeout);
|
|
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, monotonic_t timeout);
|
|
int pollForEvents(EventLoopData *eld, monotonic_t timeout, watch_callback_func);
|
|
unsigned dispatchTimers(EventLoopData *eld);
|
|
void finalizePollData(EventLoopData *eld);
|
|
bool initPollData(EventLoopData *eld, int display_fd);
|
|
void wakeupEventLoop(EventLoopData *eld);
|
|
char* utf_8_strndup(const char* source, size_t max_length);
|
|
int createAnonymousFile(off_t size);
|