Initial attempt at supporting Wayland frame events

Does not actually work because the wayland frame callback is not called
at all, fo rsome reason I cannot determine.
This commit is contained in:
Kovid Goyal 2018-10-26 07:38:47 +05:30
parent 8395076da5
commit 5b547d9b06
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 58 additions and 3 deletions

View File

@ -211,6 +211,7 @@ def generate_wrappers(glfw_header):
void glfwSetX11SelectionString(const char* string)
const char* glfwGetX11SelectionString(void)
int glfwGetXKBScancode(const char* key_name, int case_sensitive)
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))
@ -229,7 +230,7 @@ def generate_wrappers(glfw_header):
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
{}
const char* load_glfw(const char* path);

21
glfw/wl_window.c vendored
View File

@ -1929,6 +1929,18 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int
glfw_xkb_update_ime_state(w, &_glfw.wl.xkb, which, a, b, c, d);
}
struct frame_callback_data {
unsigned long long id;
void(*callback)(unsigned long long id);
};
static void
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) {
struct frame_callback_data *cbdata = (struct frame_callback_data*)data;
cbdata->callback(cbdata->id);
free(cbdata);
wl_callback_destroy(callback);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
@ -1950,3 +1962,12 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
}
GLFWAPI void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, void(*callback)(unsigned long long id)) {
_GLFWwindow* window = (_GLFWwindow*) handle;
struct frame_callback_data *cbdata = malloc(sizeof(struct frame_callback_data));
cbdata->callback = callback; cbdata->id = id;
static const struct wl_callback_listener frame_listener = { .done = frame_handle_redraw };
struct wl_callback *wlcallback = wl_surface_frame(window->wl.surface);
wl_callback_add_listener(wlcallback, &frame_listener, cbdata);
}

View File

@ -623,6 +623,7 @@ render_os_window(OSWindow *os_window, double now, unsigned int active_window_id,
os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id;
os_window->focused_at_last_render = os_window->is_focused;
os_window->is_damaged = false;
if (global_state.is_wayland) os_window->wayland_render_state = RENDER_FRAME_NOT_REQUESTED;
#undef WD
#undef TD
}
@ -638,6 +639,12 @@ render(double now) {
for (size_t i = 0; i < global_state.num_os_windows; i++) {
OSWindow *w = global_state.os_windows + i;
if (!w->num_tabs || !should_os_window_be_rendered(w)) continue;
if (global_state.is_wayland && w->wayland_render_state != RENDER_FRAME_READY) {
if (w->wayland_render_state == RENDER_FRAME_NOT_REQUESTED) {
wayland_request_frame_render(w);
}
return;
}
bool needs_render = w->is_damaged;
make_os_window_context_current(w);
if (w->viewport_size_dirty) {

2
kitty/glfw-wrapper.c generated
View File

@ -380,6 +380,8 @@ load_glfw(const char* path) {
*(void **) (&glfwGetXKBScancode_impl) = dlsym(handle, "glfwGetXKBScancode");
*(void **) (&glfwRequestWaylandFrameEvent_impl) = dlsym(handle, "glfwRequestWaylandFrameEvent");
return NULL;
}

6
kitty/glfw-wrapper.h generated
View File

@ -1387,7 +1387,7 @@ typedef struct GLFWgamepadstate
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
typedef int (*glfwInit_func)();
glfwInit_func glfwInit_impl;
#define glfwInit glfwInit_impl
@ -1892,4 +1892,8 @@ typedef int (*glfwGetXKBScancode_func)(const char*, int);
glfwGetXKBScancode_func glfwGetXKBScancode_impl;
#define glfwGetXKBScancode glfwGetXKBScancode_impl
typedef void (*glfwRequestWaylandFrameEvent_func)(GLFWwindow*, unsigned long long, GLFWwaylandframecallbackfunc);
glfwRequestWaylandFrameEvent_func glfwRequestWaylandFrameEvent_impl;
#define glfwRequestWaylandFrameEvent glfwRequestWaylandFrameEvent_impl
const char* load_glfw(const char* path);

View File

@ -559,7 +559,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
w->fonts_data = fonts_data;
w->shown_once = true;
push_focus_history(w);
glfwSwapInterval(OPT(sync_to_monitor) ? 1 : 0);
glfwSwapInterval(OPT(sync_to_monitor) && !global_state.is_wayland ? 1 : 0);
#ifdef __APPLE__
if (OPT(macos_option_as_alt)) glfwSetCocoaTextInputFilter(glfw_window, filter_option);
glfwSetCocoaToggleFullscreenIntercept(glfw_window, intercept_cocoa_fullscreen);
@ -982,6 +982,23 @@ get_cocoa_key_equivalent(int key, int mods, unsigned short *cocoa_key, int *coco
glfwGetCocoaKeyEquivalent(key, mods, cocoa_key, cocoa_mods);
}
#endif
void
wayland_frame_request_callback(id_type os_window_id) {
for (size_t i = 0; i < global_state.num_os_windows; i++) {
if (global_state.os_windows[i].id == os_window_id) {
global_state.os_windows[i].wayland_render_state = RENDER_FRAME_READY;
break;
}
}
}
void
wayland_request_frame_render(OSWindow *w) {
glfwRequestWaylandFrameEvent(w->handle, w->id, wayland_frame_request_callback);
w->wayland_render_state = RENDER_FRAME_REQUESTED;
}
// Boilerplate {{{
static PyMethodDef module_methods[] = {

View File

@ -98,6 +98,7 @@ typedef struct {
bool is_set;
} OSWindowGeometry;
enum WAYLAND_RENDER_STATE { RENDER_FRAME_NOT_REQUESTED, RENDER_FRAME_REQUESTED, RENDER_FRAME_READY };
typedef struct {
void *handle;
@ -127,6 +128,7 @@ typedef struct {
FONTS_DATA_HANDLE fonts_data;
id_type temp_font_group_id;
double pending_scroll_pixels;
enum WAYLAND_RENDER_STATE wayland_render_state;
} OSWindow;
@ -204,3 +206,4 @@ typedef enum {
void set_cocoa_pending_action(CocoaPendingAction action);
bool application_quit_requested();
#endif
void wayland_request_frame_render(OSWindow *w);