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_xwayland_surface *xwayland_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 been_mapped;
int x, y;
int x, y, w, h;
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 {

View file

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

View file

@ -1,4 +1,6 @@
#include "labwc.h"
#include "common/log.h"
#include "common/bug-on.h"
struct xdg_deco {
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
@ -63,6 +65,14 @@ static bool has_ssd(struct view *view)
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)
{
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->been_mapped = true;
wl_signal_add(&view->xdg_surface->surface->events.commit,
&view->commit);
view->commit.notify = handle_commit;
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);
view->mapped = false;
wl_list_remove(&view->commit.link);
view_focus(next_toplevel(view));
}

View file

@ -1,5 +1,6 @@
#include "labwc.h"
#include "common/log.h"
#include "common/bug-on.h"
static bool has_ssd(struct view *view)
{
@ -11,6 +12,16 @@ static bool has_ssd(struct view *view)
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)
{
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->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);
}
@ -30,6 +50,7 @@ void xwl_surface_unmap(struct wl_listener *listener, void *data)
{
struct view *view = wl_container_of(listener, view, unmap);
view->mapped = false;
wl_list_remove(&view->commit.link);
/*
* 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'