Handle commit signal

wlr_surface can change during xwayland map/unmap, so let's only update
view width and height after commit signal has been received.
This commit is contained in:
Johan Malm 2020-08-31 08:12:44 +01:00
parent 9d408aad73
commit 127eddfd96
4 changed files with 57 additions and 25 deletions

View file

@ -111,17 +111,19 @@ struct view {
struct wlr_xdg_surface *xdg_surface; struct wlr_xdg_surface *xdg_surface;
struct wlr_xwayland_surface *xwayland_surface; struct wlr_xwayland_surface *xwayland_surface;
struct wlr_surface *surface; struct wlr_surface *surface;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
struct wl_listener request_move;
struct wl_listener request_resize;
struct wl_listener request_configure;
bool mapped; bool mapped;
bool been_mapped; bool been_mapped;
int x, y; int x, y, w, h;
bool show_server_side_deco; bool show_server_side_deco;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;
struct wl_listener request_configure;
}; };
struct keyboard { struct keyboard {

View file

@ -17,9 +17,8 @@ struct wlr_box deco_max_extents(struct view *view)
struct wlr_box box = { struct wlr_box box = {
.x = view->x - BORDER_WIDTH, .x = view->x - BORDER_WIDTH,
.y = view->y - rc.title_height - BORDER_WIDTH, .y = view->y - rc.title_height - BORDER_WIDTH,
.width = view->surface->current.width + 2 * BORDER_WIDTH, .width = view->w + 2 * BORDER_WIDTH,
.height = view->surface->current.height + rc.title_height + .height = view->h + rc.title_height + 2 * BORDER_WIDTH,
2 * BORDER_WIDTH,
}; };
return box; return box;
} }
@ -35,8 +34,7 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
return box; return box;
BUG_ON(!view->been_mapped); BUG_ON(!view->been_mapped);
BUG_ON(!view->show_server_side_deco); BUG_ON(!view->show_server_side_deco);
if ((view->surface->current.width < 1) || if ((view->w < 1) || (view->h < 1)) {
(view->surface->current.height < 1)) {
warn("view (%p) has no width/height", view); warn("view (%p) has no width/height", view);
return box; return box;
} }
@ -45,55 +43,52 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
wlr_texture_get_size(theme.xbm_close_active_unpressed, wlr_texture_get_size(theme.xbm_close_active_unpressed,
&box.width, &box.height); &box.width, &box.height);
margin = (rc.title_height - box.height) / 2; margin = (rc.title_height - box.height) / 2;
box.x = view->x + view->surface->current.width + margin - box.x = view->x + view->w + margin - rc.title_height;
rc.title_height;
box.y = view->y - rc.title_height + margin; box.y = view->y - rc.title_height + margin;
break; break;
case LAB_DECO_BUTTON_MAXIMIZE: case LAB_DECO_BUTTON_MAXIMIZE:
wlr_texture_get_size(theme.xbm_maximize_active_unpressed, wlr_texture_get_size(theme.xbm_maximize_active_unpressed,
&box.width, &box.height); &box.width, &box.height);
margin = (rc.title_height - box.height) / 2; margin = (rc.title_height - box.height) / 2;
box.x = view->x + view->surface->current.width + margin - box.x = view->x + view->w + margin - rc.title_height * 2;
rc.title_height * 2;
box.y = view->y - rc.title_height + margin; box.y = view->y - rc.title_height + margin;
break; break;
case LAB_DECO_BUTTON_ICONIFY: case LAB_DECO_BUTTON_ICONIFY:
wlr_texture_get_size(theme.xbm_iconify_active_unpressed, wlr_texture_get_size(theme.xbm_iconify_active_unpressed,
&box.width, &box.height); &box.width, &box.height);
margin = (rc.title_height - box.height) / 2; margin = (rc.title_height - box.height) / 2;
box.x = view->x + view->surface->current.width + margin - box.x = view->x + view->w + margin - rc.title_height * 3;
rc.title_height * 3;
box.y = view->y - rc.title_height + margin; box.y = view->y - rc.title_height + margin;
break; break;
case LAB_DECO_PART_TITLE: case LAB_DECO_PART_TITLE:
box.x = view->x; box.x = view->x;
box.y = view->y - rc.title_height; box.y = view->y - rc.title_height;
box.width = view->surface->current.width; box.width = view->w;
box.height = rc.title_height; box.height = rc.title_height;
break; break;
case LAB_DECO_PART_TOP: case LAB_DECO_PART_TOP:
box.x = view->x - BORDER_WIDTH; box.x = view->x - BORDER_WIDTH;
box.y = view->y - rc.title_height - BORDER_WIDTH; box.y = view->y - rc.title_height - BORDER_WIDTH;
box.width = view->surface->current.width + 2 * BORDER_WIDTH; box.width = view->w + 2 * BORDER_WIDTH;
box.height = BORDER_WIDTH; box.height = BORDER_WIDTH;
break; break;
case LAB_DECO_PART_RIGHT: case LAB_DECO_PART_RIGHT:
box.x = view->x + view->surface->current.width; box.x = view->x + view->w;
box.y = view->y - rc.title_height; box.y = view->y - rc.title_height;
box.width = BORDER_WIDTH; box.width = BORDER_WIDTH;
box.height = view->surface->current.height + rc.title_height; box.height = view->h + rc.title_height;
break; break;
case LAB_DECO_PART_BOTTOM: case LAB_DECO_PART_BOTTOM:
box.x = view->x - BORDER_WIDTH; box.x = view->x - BORDER_WIDTH;
box.y = view->y + view->surface->current.height; box.y = view->y + view->h;
box.width = view->surface->current.width + 2 * BORDER_WIDTH; box.width = view->w + 2 * BORDER_WIDTH;
box.height = +BORDER_WIDTH; box.height = +BORDER_WIDTH;
break; break;
case LAB_DECO_PART_LEFT: case LAB_DECO_PART_LEFT:
box.x = view->x - BORDER_WIDTH; box.x = view->x - BORDER_WIDTH;
box.y = view->y - rc.title_height; box.y = view->y - rc.title_height;
box.width = BORDER_WIDTH; box.width = BORDER_WIDTH;
box.height = view->surface->current.height + rc.title_height; box.height = view->h + rc.title_height;
break; break;
default: default:
break; break;

View file

@ -1,4 +1,6 @@
#include "labwc.h" #include "labwc.h"
#include "common/log.h"
#include "common/bug-on.h"
struct xdg_deco { struct xdg_deco {
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration; struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
@ -63,6 +65,14 @@ static bool has_ssd(struct view *view)
return true; return true;
} }
static void handle_commit(struct wl_listener *listener, void *data)
{
struct view *view = wl_container_of(listener, view, commit);
BUG_ON(!view->surface);
view->w = view->surface->current.width;
view->h = view->surface->current.height;
}
void xdg_surface_map(struct wl_listener *listener, void *data) void xdg_surface_map(struct wl_listener *listener, void *data)
{ {
struct view *view = wl_container_of(listener, view, map); struct view *view = wl_container_of(listener, view, map);
@ -73,6 +83,9 @@ void xdg_surface_map(struct wl_listener *listener, void *data)
view_init_position(view); view_init_position(view);
} }
view->been_mapped = true; view->been_mapped = true;
wl_signal_add(&view->xdg_surface->surface->events.commit,
&view->commit);
view->commit.notify = handle_commit;
view_focus(view); view_focus(view);
} }
@ -80,6 +93,7 @@ void xdg_surface_unmap(struct wl_listener *listener, void *data)
{ {
struct view *view = wl_container_of(listener, view, unmap); struct view *view = wl_container_of(listener, view, unmap);
view->mapped = false; view->mapped = false;
wl_list_remove(&view->commit.link);
view_focus(next_toplevel(view)); view_focus(next_toplevel(view));
} }

View file

@ -1,5 +1,6 @@
#include "labwc.h" #include "labwc.h"
#include "common/log.h" #include "common/log.h"
#include "common/bug-on.h"
static bool has_ssd(struct view *view) static bool has_ssd(struct view *view)
{ {
@ -11,6 +12,16 @@ static bool has_ssd(struct view *view)
return true; return true;
} }
static void handle_commit(struct wl_listener *listener, void *data)
{
struct view *view = wl_container_of(listener, view, commit);
BUG_ON(!view->surface);
/* Must receive commit signal before accessing surface->current* */
view->w = view->surface->current.width;
view->h = view->surface->current.height;
}
void xwl_surface_map(struct wl_listener *listener, void *data) void xwl_surface_map(struct wl_listener *listener, void *data)
{ {
struct view *view = wl_container_of(listener, view, map); struct view *view = wl_container_of(listener, view, map);
@ -23,6 +34,15 @@ void xwl_surface_map(struct wl_listener *listener, void *data)
view_init_position(view); view_init_position(view);
} }
view->been_mapped = true; view->been_mapped = true;
/*
* Add commit listener here, because xwayland map/unmap can change
* the wlr_surface
*/
wl_signal_add(&view->xwayland_surface->surface->events.commit,
&view->commit);
view->commit.notify = handle_commit;
view_focus(view); view_focus(view);
} }
@ -30,6 +50,7 @@ void xwl_surface_unmap(struct wl_listener *listener, void *data)
{ {
struct view *view = wl_container_of(listener, view, unmap); struct view *view = wl_container_of(listener, view, unmap);
view->mapped = false; view->mapped = false;
wl_list_remove(&view->commit.link);
/* /*
* Note that if 'view' is not a toplevel view, the 'front' toplevel view * Note that if 'view' is not a toplevel view, the 'front' toplevel view
* will be focussed on; but if 'view' is a toplevel view, the 'next' * will be focussed on; but if 'view' is a toplevel view, the 'next'