mirror of
https://github.com/fltk/fltk.git
synced 2026-05-28 20:06:18 +08:00
Fix "New Wayland subwindow code creates issues with resizes of opengl windows…" (#1311)
This commit is contained in:
@@ -300,6 +300,7 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
|
|||||||
if (is_a_resize) valid(0);
|
if (is_a_resize) valid(0);
|
||||||
pGlWindowDriver->resize(is_a_resize, W, H);
|
pGlWindowDriver->resize(is_a_resize, W, H);
|
||||||
Fl_Window::resize(X,Y,W,H);
|
Fl_Window::resize(X,Y,W,H);
|
||||||
|
if (is_a_resize) pGlWindowDriver->after_resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public:
|
|||||||
virtual void make_current_after() {}
|
virtual void make_current_after() {}
|
||||||
virtual void swap_buffers() {}
|
virtual void swap_buffers() {}
|
||||||
virtual void resize(int /*is_a_resize*/, int /*w*/, int /*h*/) {}
|
virtual void resize(int /*is_a_resize*/, int /*w*/, int /*h*/) {}
|
||||||
|
virtual void after_resize() {}
|
||||||
virtual char swap_type();
|
virtual char swap_type();
|
||||||
virtual void swap_interval(int) { }
|
virtual void swap_interval(int) { }
|
||||||
virtual int swap_interval() const { return -1; }
|
virtual int swap_interval() const { return -1; }
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ private:
|
|||||||
int mode_(int m, const int *a) FL_OVERRIDE;
|
int mode_(int m, const int *a) FL_OVERRIDE;
|
||||||
void swap_buffers() FL_OVERRIDE;
|
void swap_buffers() FL_OVERRIDE;
|
||||||
void resize(int is_a_resize, int w, int h) FL_OVERRIDE;
|
void resize(int is_a_resize, int w, int h) FL_OVERRIDE;
|
||||||
|
void after_resize() FL_OVERRIDE;
|
||||||
char swap_type() FL_OVERRIDE;
|
char swap_type() FL_OVERRIDE;
|
||||||
void swap_interval(int) FL_OVERRIDE;
|
void swap_interval(int) FL_OVERRIDE;
|
||||||
int swap_interval() const FL_OVERRIDE;
|
int swap_interval() const FL_OVERRIDE;
|
||||||
|
|||||||
@@ -406,6 +406,14 @@ void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fl_Wayland_Gl_Window_Driver::after_resize() {
|
||||||
|
Fl_Window *parent = (pWindow->parent() ? pWindow->window() : NULL);
|
||||||
|
struct wld_window *xid = (parent ? fl_wl_xid(parent) : NULL);
|
||||||
|
if (xid && !xid->frame_cb) {
|
||||||
|
eglSwapBuffers(Fl_Wayland_Gl_Window_Driver::egl_display, egl_surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char Fl_Wayland_Gl_Window_Driver::swap_type() {
|
char Fl_Wayland_Gl_Window_Driver::swap_type() {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ struct wld_window {
|
|||||||
struct wl_callback *frame_cb;
|
struct wl_callback *frame_cb;
|
||||||
struct Fl_Wayland_Graphics_Driver::wld_buffer *buffer;
|
struct Fl_Wayland_Graphics_Driver::wld_buffer *buffer;
|
||||||
struct xdg_surface *xdg_surface;
|
struct xdg_surface *xdg_surface;
|
||||||
enum Fl_Wayland_Window_Driver::kind kind;
|
|
||||||
union { // for each value of kind
|
union { // for each value of kind
|
||||||
struct libdecor_frame *frame;
|
struct libdecor_frame *frame;
|
||||||
struct wl_subsurface *subsurface;
|
struct wl_subsurface *subsurface;
|
||||||
@@ -158,6 +157,7 @@ struct wld_window {
|
|||||||
};
|
};
|
||||||
// non-null when using custom cursor
|
// non-null when using custom cursor
|
||||||
struct Fl_Wayland_Window_Driver::custom_cursor *custom_cursor;
|
struct Fl_Wayland_Window_Driver::custom_cursor *custom_cursor;
|
||||||
|
enum Fl_Wayland_Window_Driver::kind kind;
|
||||||
int configured_width;
|
int configured_width;
|
||||||
int configured_height;
|
int configured_height;
|
||||||
int floating_width;
|
int floating_width;
|
||||||
|
|||||||
@@ -1452,7 +1452,7 @@ void Fl_Wayland_Window_Driver::makeWindow()
|
|||||||
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||||
|
|
||||||
new_window->wl_surface = wl_compositor_create_surface(scr_driver->wl_compositor);
|
new_window->wl_surface = wl_compositor_create_surface(scr_driver->wl_compositor);
|
||||||
//Fl::warning("makeWindow:%p wayland-scale=%d user-scale=%.2f\n", pWindow, new_window->scale, Fl::screen_scale(0));
|
//printf("makeWindow:%p %s %s\n", pWindow, pWindow->parent()?"SUB":"", pWindow->as_gl_window()?"GL":"");
|
||||||
wl_surface_add_listener(new_window->wl_surface, &surface_listener, new_window);
|
wl_surface_add_listener(new_window->wl_surface, &surface_listener, new_window);
|
||||||
|
|
||||||
if (!shape()) { // rectangular FLTK windows are opaque
|
if (!shape()) { // rectangular FLTK windows are opaque
|
||||||
@@ -1841,9 +1841,14 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
|||||||
}
|
}
|
||||||
Fl_Window *parent = this->parent() ? pWindow->window() : NULL;
|
Fl_Window *parent = this->parent() ? pWindow->window() : NULL;
|
||||||
struct wld_window *parent_xid = parent ? fl_wl_xid(parent) : NULL;
|
struct wld_window *parent_xid = parent ? fl_wl_xid(parent) : NULL;
|
||||||
// When moving or resizing a subwindow independently from its parent, skip the move/resize
|
//printf("resize[%p] %dx%d is_a_resize=%d is_a_move=%d depth=%d parent_xid->frame_cb=%p\n", pWindow,W,H,is_a_resize,is_a_move,depth, (parent_xid?parent_xid->frame_cb:0) );
|
||||||
// operation if the parent window is being redrawn, in line with the frame callback mechanism.
|
if (depth == 1 && fl_win && parent_xid && parent_xid->frame_cb && can_expand_outside_parent_) {
|
||||||
if (depth == 1 && fl_win && parent_xid && parent_xid->frame_cb && is_a_move) {
|
// When moving or resizing a subwindow independently from its parent while the parent window
|
||||||
|
// is being redrawn, the processing depends on whether the moved/resize window
|
||||||
|
// is a draggable-subwindow. For a draggable subwindow having can_expand_outside_parent_ != 0,
|
||||||
|
// skip the X,Y,W,H tuple to process only tuples received when parent window is ready.
|
||||||
|
// This smoothes the movement of the draggable subwindow.
|
||||||
|
// Process regular subwindows normally.
|
||||||
depth--;
|
depth--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1917,13 +1922,19 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
|||||||
wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
|
wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
|
||||||
wl_surface_commit(parent_xid->wl_surface);
|
wl_surface_commit(parent_xid->wl_surface);
|
||||||
}
|
}
|
||||||
} else if (is_a_move && !parent_xid->frame_cb) {
|
} else if (parent_xid->buffer && is_a_move) {
|
||||||
// Use the frame callback mechanism applied to the object's parent window
|
|
||||||
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
|
|
||||||
wl_callback_add_listener(parent_xid->frame_cb,
|
|
||||||
Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
|
|
||||||
if (fl_win->subsurface) wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
|
if (fl_win->subsurface) wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
|
||||||
wl_surface_commit(parent_xid->wl_surface);
|
if (!parent_xid->buffer->wl_buffer || parent_xid->buffer->draw_buffer_needs_commit) {
|
||||||
|
if (!parent_xid->frame_cb) Fl_Wayland_Graphics_Driver::buffer_commit(parent_xid);
|
||||||
|
} else {
|
||||||
|
if (!parent_xid->frame_cb) {
|
||||||
|
// Use the frame callback mechanism applied to the object's parent window
|
||||||
|
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
|
||||||
|
wl_callback_add_listener(parent_xid->frame_cb,
|
||||||
|
Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
|
||||||
|
}
|
||||||
|
wl_surface_commit(parent_xid->wl_surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
checkSubwindowFrame(); // make sure subwindow doesn't leak outside parent
|
checkSubwindowFrame(); // make sure subwindow doesn't leak outside parent
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user