mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
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:
parent
9d408aad73
commit
127eddfd96
4 changed files with 57 additions and 25 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
31
src/deco.c
31
src/deco.c
|
|
@ -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;
|
||||||
|
|
|
||||||
14
src/xdg.c
14
src/xdg.c
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
src/xwl.c
21
src/xwl.c
|
|
@ -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'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue