Wayland: fix interactive moving and resizing of a subwindow - cont'd (#987)
This fix requires to be able to recognize whether Fl_Wayland_Window_Driver::resize() is called by a resize operation of an encompassing widget or not. To do that, private static int variable group_resize_depth_ is added to class Fl_Group and an accessor to this variable is added to class Fl_Window_Driver.
This commit is contained in:
parent
55daede41d
commit
1c6a0c1a8f
@ -54,7 +54,7 @@ class Fl_Rect;
|
|||||||
reason \p FL_REASON_CLOSED.
|
reason \p FL_REASON_CLOSED.
|
||||||
*/
|
*/
|
||||||
class FL_EXPORT Fl_Group : public Fl_Widget {
|
class FL_EXPORT Fl_Group : public Fl_Widget {
|
||||||
|
friend class Fl_Window_Driver;
|
||||||
union {
|
union {
|
||||||
Fl_Widget** array_; // used if group has two or more children or NULL
|
Fl_Widget** array_; // used if group has two or more children or NULL
|
||||||
Fl_Widget* child1_; // used if group has one child or NULL
|
Fl_Widget* child1_; // used if group has one child or NULL
|
||||||
@ -67,6 +67,7 @@ class FL_EXPORT Fl_Group : public Fl_Widget {
|
|||||||
|
|
||||||
int navigation(int);
|
int navigation(int);
|
||||||
static Fl_Group *current_;
|
static Fl_Group *current_;
|
||||||
|
static int group_resize_depth_;
|
||||||
|
|
||||||
// unimplemented copy ctor and assignment operator
|
// unimplemented copy ctor and assignment operator
|
||||||
Fl_Group(const Fl_Group&);
|
Fl_Group(const Fl_Group&);
|
||||||
|
@ -809,6 +809,8 @@ int* Fl_Group::sizes()
|
|||||||
return sizes_;
|
return sizes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Fl_Group::group_resize_depth_ = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Resizes the Fl_Group widget and all of its children.
|
Resizes the Fl_Group widget and all of its children.
|
||||||
|
|
||||||
@ -857,6 +859,7 @@ void Fl_Group::resize(int X, int Y, int W, int H) {
|
|||||||
// Part 2: here we definitely have a resizable() widget, resize children
|
// Part 2: here we definitely have a resizable() widget, resize children
|
||||||
|
|
||||||
else if (children_) {
|
else if (children_) {
|
||||||
|
group_resize_depth_++;
|
||||||
|
|
||||||
// get changes in size/position from the initial size:
|
// get changes in size/position from the initial size:
|
||||||
dx = X - p->x();
|
dx = X - p->x();
|
||||||
@ -905,6 +908,7 @@ void Fl_Group::resize(int X, int Y, int W, int H) {
|
|||||||
|
|
||||||
o->resize(L+dx, T+dy, R-L, B-T);
|
o->resize(L+dx, T+dy, R-L, B-T);
|
||||||
}
|
}
|
||||||
|
group_resize_depth_--;
|
||||||
} // End of part 2: we have a resizable() widget
|
} // End of part 2: we have a resizable() widget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
Fl_Window *pWindow;
|
Fl_Window *pWindow;
|
||||||
int screen_num_; // number of screen where window is mapped
|
int screen_num_; // number of screen where window is mapped
|
||||||
|
static int group_resize_depth() { return Fl_Group::group_resize_depth_; }
|
||||||
public:
|
public:
|
||||||
Fl_Window_Driver(Fl_Window *);
|
Fl_Window_Driver(Fl_Window *);
|
||||||
virtual ~Fl_Window_Driver();
|
virtual ~Fl_Window_Driver();
|
||||||
|
@ -1770,7 +1770,6 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx
|
|||||||
|
|
||||||
|
|
||||||
void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
||||||
static int depth = 0;
|
|
||||||
struct wld_window *fl_win = fl_wl_xid(pWindow);
|
struct wld_window *fl_win = fl_wl_xid(pWindow);
|
||||||
if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) {
|
if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) {
|
||||||
pWindow->wait_for_expose();
|
pWindow->wait_for_expose();
|
||||||
@ -1788,14 +1787,13 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
|||||||
int is_a_resize = (W != w() || H != h() || true_rescale);
|
int is_a_resize = (W != w() || H != h() || true_rescale);
|
||||||
if (is_a_move) force_position(1);
|
if (is_a_move) force_position(1);
|
||||||
else if (!is_a_resize && !is_a_move) return;
|
else if (!is_a_resize && !is_a_move) return;
|
||||||
depth++;
|
|
||||||
if (shown() && !(parent() || popup_window())) {
|
if (shown() && !(parent() || popup_window())) {
|
||||||
X = Y = 0;
|
X = Y = 0;
|
||||||
}
|
}
|
||||||
struct wld_window *parent_xid = parent() ? fl_wl_xid(pWindow->window()) : NULL;
|
struct wld_window *parent_xid = parent() ? fl_wl_xid(pWindow->window()) : NULL;
|
||||||
// This condition excludes moving or resizing a subwindow while not changing its parent
|
// This condition excludes moving or resizing a subwindow while not changing its parent
|
||||||
// and delays application of new X,Y,W,H values if the parent is being committed.
|
// and delays application of new X,Y,W,H values if the parent is being committed.
|
||||||
if (!parent_xid || depth > 1 || !parent_xid->frame_cb) {
|
if (true_rescale || !parent_xid || group_resize_depth() >= 1 || !parent_xid->frame_cb) {
|
||||||
if (is_a_resize) {
|
if (is_a_resize) {
|
||||||
if (pWindow->parent()) {
|
if (pWindow->parent()) {
|
||||||
if (W < 1) W = 1;
|
if (W < 1) W = 1;
|
||||||
@ -1866,18 +1864,16 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fl_win && parent_xid) {
|
if (fl_win && parent_xid) {
|
||||||
if (depth == 1) {
|
if (group_resize_depth() < 1 && !parent_xid->frame_cb) {
|
||||||
// Interactive move or resize of a subwindow requires to commit the parent surface
|
// Interactive move or resize of a subwindow requires to commit the parent surface
|
||||||
// and requires to make sure the parent surface is ready to accept a new commit (#987).
|
// and requires to make sure the parent surface is ready to accept a new commit (#987).
|
||||||
if (!parent_xid->frame_cb) {
|
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
|
||||||
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
|
wl_callback_add_listener(parent_xid->frame_cb,
|
||||||
wl_callback_add_listener(parent_xid->frame_cb, Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
|
Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
|
||||||
wl_surface_commit(parent_xid->wl_surface);
|
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
|
||||||
}
|
}
|
||||||
depth--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user