mirror of
https://github.com/fltk/fltk.git
synced 2026-05-28 11:25:22 +08:00
Implement Fl_Wayland_Screen_Driver::poll_or_select_with_delay(double)
This commit is contained in:
@@ -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()
|
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
|
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
|
with calls to <tt>eglGetDisplay(), eglInitialize()</tt>, and \c eglBindAPI().
|
||||||
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.
|
|
||||||
|
|
||||||
Member function \c Fl_Wayland_Gl_Window_Driver::find() calls \c eglChooseConfig()
|
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(),
|
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
|
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
|
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
|
emulate an overlay buffer to support Fl_Gl_Window objects overriding their
|
||||||
\c draw_overlay() member function.
|
\c draw_overlay() member function. Then, it calls function \c eglSwapBuffers().
|
||||||
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).
|
|
||||||
|
|
||||||
The overridden \c Fl_Wayland_Gl_Window_Driver::resize() function is implemented with
|
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().
|
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).
|
// 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
|
// 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
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
@@ -39,7 +39,6 @@ private:
|
|||||||
static EGLDisplay egl_display;
|
static EGLDisplay egl_display;
|
||||||
struct wl_egl_window *egl_window;
|
struct wl_egl_window *egl_window;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
bool egl_swap_in_progress;
|
|
||||||
Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win);
|
Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win);
|
||||||
float pixels_per_unit() FL_OVERRIDE;
|
float pixels_per_unit() FL_OVERRIDE;
|
||||||
void make_current_before() 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();
|
if (egl_display == EGL_NO_DISPLAY) init();
|
||||||
egl_window = NULL;
|
egl_window = NULL;
|
||||||
egl_surface = 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 (!overlay_buffer) return; // don't call eglSwapBuffers until overlay has been drawn
|
||||||
}
|
}
|
||||||
|
|
||||||
if (egl_surface && !egl_swap_in_progress) {
|
if (egl_surface) {
|
||||||
egl_swap_in_progress = true; // prevents crash while down resizing rotating glpuzzle
|
|
||||||
wl_display_dispatch_pending(Fl_Wayland_Screen_Driver::wl_display);
|
|
||||||
eglSwapBuffers(Fl_Wayland_Gl_Window_Driver::egl_display, 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;
|
int get_key(int k) FL_OVERRIDE;
|
||||||
void enable_im() FL_OVERRIDE;
|
void enable_im() FL_OVERRIDE;
|
||||||
void disable_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
|
// Wayland-specific member functions
|
||||||
void screen_count_set(int count) {num_screens = count;}
|
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) {
|
int Fl_Wayland_Screen_Driver::event_key(int k) {
|
||||||
if (k >= 'A' && k <= 'Z') k += 32;
|
if (k >= 'A' && k <= 'Z') k += 32;
|
||||||
return (search_int_vector(key_vector, k) >= 0);
|
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() {
|
void Fl_Wayland_Window_Driver::hide() {
|
||||||
Fl_X* ip = Fl_X::flx(pWindow);
|
Fl_X* ip = Fl_X::flx(pWindow);
|
||||||
if (hide_common()) return;
|
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);
|
//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);
|
free(wld_win);
|
||||||
}
|
}
|
||||||
if (pWindow->as_gl_window() && in_flush_) {
|
delete ip;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user