mirror of https://github.com/fltk/fltk
Implement Fl_Wayland_Screen_Driver::poll_or_select_with_delay(double)
This commit is contained in:
parent
b1ab37eeff
commit
7feddabd24
|
@ -1056,10 +1056,7 @@ native platform window system. OpenGL-using FLTK apps are therefore linked to \c
|
|||
|
||||
EGL is initialized calling member function \c Fl_Wayland_Gl_Window_Driver::init()
|
||||
once, the first time the \c Fl_Wayland_Gl_Window_Driver c'tor runs. That is done
|
||||
with calls to <tt>eglGetDisplay(), eglInitialize(), eglGetConfigs(), and
|
||||
eglBindAPI()</tt>. Function \c eglGetConfigs() computes the number of usable
|
||||
EGL frame buffer configurations for the display and stores it in static member variable
|
||||
\c Fl_Wayland_Gl_Window_Driver::configs_count.
|
||||
with calls to <tt>eglGetDisplay(), eglInitialize()</tt>, and \c eglBindAPI().
|
||||
|
||||
Member function \c Fl_Wayland_Gl_Window_Driver::find() calls \c eglChooseConfig()
|
||||
to filter the set of GL configurations that match the \c Fl_Gl_Window's mode(),
|
||||
|
@ -1089,16 +1086,7 @@ FLTK function \c Fl_Gl_Window::make_current() calls overridden function
|
|||
FLTK calls function \c Fl_Wayland_Gl_Window_Driver::swap_buffers() each time it wants a
|
||||
GL context to be sent to the display. This function contains some pure GL code to
|
||||
emulate an overlay buffer to support Fl_Gl_Window objects overriding their
|
||||
\c draw_overlay() member function.
|
||||
Then, it calls function \c eglSwapBuffers() after having called
|
||||
\c wl_display_dispatch_pending() to synchronize EGL use
|
||||
with the rest of the Wayland compositor's activity.
|
||||
Function \c wl_display_dispatch_pending() calls the listeners attached to
|
||||
commands the Wayland compositor recently sent to the client.
|
||||
The fact that this function gets called during the process of drawing an Fl_Gl_Window
|
||||
makes possible a scenario that cannot occur with other FLTK platforms : a GL window can be
|
||||
closed while being drawn. Function \c Fl_Wayland_Window_Driver::hide() is written to
|
||||
handle such scenario without error (see comments therein).
|
||||
\c draw_overlay() member function. Then, it calls function \c eglSwapBuffers().
|
||||
|
||||
The overridden \c Fl_Wayland_Gl_Window_Driver::resize() function is implemented with
|
||||
calls to \c wl_egl_window_get_attached_size() and \c wl_egl_window_resize().
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// Class Fl_Wayland_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021-2022 by Bill Spitzak and others.
|
||||
// Copyright 2021-2023 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
|
@ -39,7 +39,6 @@ private:
|
|||
static EGLDisplay egl_display;
|
||||
struct wl_egl_window *egl_window;
|
||||
EGLSurface egl_surface;
|
||||
bool egl_swap_in_progress;
|
||||
Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win);
|
||||
float pixels_per_unit() FL_OVERRIDE;
|
||||
void make_current_before() FL_OVERRIDE;
|
||||
|
|
|
@ -69,7 +69,6 @@ Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) : Fl
|
|||
if (egl_display == EGL_NO_DISPLAY) init();
|
||||
egl_window = NULL;
|
||||
egl_surface = NULL;
|
||||
egl_swap_in_progress = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,11 +341,8 @@ void Fl_Wayland_Gl_Window_Driver::swap_buffers() {
|
|||
if (!overlay_buffer) return; // don't call eglSwapBuffers until overlay has been drawn
|
||||
}
|
||||
|
||||
if (egl_surface && !egl_swap_in_progress) {
|
||||
egl_swap_in_progress = true; // prevents crash while down resizing rotating glpuzzle
|
||||
wl_display_dispatch_pending(Fl_Wayland_Screen_Driver::wl_display);
|
||||
if (egl_surface) {
|
||||
eglSwapBuffers(Fl_Wayland_Gl_Window_Driver::egl_display, egl_surface);
|
||||
egl_swap_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -168,6 +168,10 @@ public:
|
|||
int get_key(int k) FL_OVERRIDE;
|
||||
void enable_im() FL_OVERRIDE;
|
||||
void disable_im() FL_OVERRIDE;
|
||||
|
||||
// overridden functions from parent class Fl_Unix_Screen_Driver
|
||||
int poll_or_select_with_delay(double time_to_wait) FL_OVERRIDE;
|
||||
int poll_or_select() FL_OVERRIDE;
|
||||
|
||||
// Wayland-specific member functions
|
||||
void screen_count_set(int count) {num_screens = count;}
|
||||
|
|
|
@ -1681,6 +1681,21 @@ void *Fl_Wayland_Screen_Driver::control_maximize_button(void *data) {
|
|||
}
|
||||
|
||||
|
||||
int Fl_Wayland_Screen_Driver::poll_or_select_with_delay(double time_to_wait) {
|
||||
wl_display_dispatch_pending(wl_display);
|
||||
return Fl_Unix_Screen_Driver::poll_or_select_with_delay(time_to_wait);
|
||||
}
|
||||
|
||||
|
||||
// like Fl_Wayland_Screen_Driver::poll_or_select_with_delay(0.0) except no callbacks are done:
|
||||
int Fl_Wayland_Screen_Driver::poll_or_select() {
|
||||
int ret = wl_display_prepare_read(wl_display);
|
||||
if (ret == 0) wl_display_cancel_read(wl_display);
|
||||
else return 1;
|
||||
return Fl_Unix_Screen_Driver::poll_or_select();
|
||||
}
|
||||
|
||||
|
||||
int Fl_Wayland_Screen_Driver::event_key(int k) {
|
||||
if (k >= 'A' && k <= 'Z') k += 32;
|
||||
return (search_int_vector(key_vector, k) >= 0);
|
||||
|
|
|
@ -427,12 +427,6 @@ static void destroy_surface_caution_pointer_focus(struct wl_surface *surface,
|
|||
}
|
||||
|
||||
|
||||
static void delayed_delete_Fl_X(void *data) {
|
||||
Fl::remove_check(delayed_delete_Fl_X, data);
|
||||
delete (Fl_X*)data;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Window_Driver::hide() {
|
||||
Fl_X* ip = Fl_X::flx(pWindow);
|
||||
if (hide_common()) return;
|
||||
|
@ -483,22 +477,7 @@ void Fl_Wayland_Window_Driver::hide() {
|
|||
//fprintf(stderr, "After hide: sub=%p frame=%p xdg=%p top=%p pop=%p surf=%p\n", wld_win->subsurface, wld_win->frame, wld_win->xdg_surface, wld_win->xdg_toplevel, wld_win->xdg_popup, wld_win->wl_surface);
|
||||
free(wld_win);
|
||||
}
|
||||
if (pWindow->as_gl_window() && in_flush_) {
|
||||
// Under Wayland and for a GL window, this summarized scenario can occur
|
||||
// when closing a window with "escape" (e.g. test/cube):
|
||||
// Fl::flush() calls Fl_Wayland_Window_Driver::flush()
|
||||
// calls Fl_Wayland_Gl_Window_Driver::swap_buffers()
|
||||
// calls wl_display_dispatch_pending() calls Fl_Wayland_Window_Driver::hide().
|
||||
// We make sure here to force exit from the loop over all damaged windows
|
||||
// in Fl::flush(), and postpone deletion of the Fl_X record until after return
|
||||
// from Fl::flush().
|
||||
ip->xid = 0;
|
||||
ip->next = NULL;
|
||||
Fl::damage(1); // make sure potential remaining damaged windows get drawn
|
||||
Fl::add_check(delayed_delete_Fl_X, ip);
|
||||
} else {
|
||||
delete ip;
|
||||
}
|
||||
delete ip;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue