mirror of
https://github.com/labwc/labwc.git
synced 2025-11-30 06:59:52 -05:00
Chase wlroots: Unified mapping
Need to handle new unified mapping, where mapping is attached to the wlr_surface objects instead of their parents. Also, most of them require a new associate event for xsurface objects, their surface member will be NULL before this event is received. Refactored by jlindgren: - add struct mappable - unify map/unmap logic
This commit is contained in:
parent
bf576e97de
commit
d7dc6e01b4
10 changed files with 142 additions and 52 deletions
|
|
@ -70,6 +70,13 @@ enum view_wants_focus {
|
|||
struct view;
|
||||
struct wlr_surface;
|
||||
|
||||
/* Common to struct view and struct xwayland_unmanaged */
|
||||
struct mappable {
|
||||
bool connected;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
};
|
||||
|
||||
/* Basic size hints (subset of XSizeHints from X11) */
|
||||
struct view_size_hints {
|
||||
int min_width;
|
||||
|
|
@ -194,8 +201,8 @@ struct view {
|
|||
struct wl_listener destroy;
|
||||
} toplevel;
|
||||
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct mappable mappable;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener surface_destroy;
|
||||
struct wl_listener commit;
|
||||
|
|
@ -345,6 +352,10 @@ view_is_focusable(struct view *view) {
|
|||
return view_is_focusable_from(view, NULL);
|
||||
}
|
||||
|
||||
void mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
|
||||
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap);
|
||||
void mappable_disconnect(struct mappable *mappable);
|
||||
|
||||
void view_toggle_keybinds(struct view *view);
|
||||
|
||||
void view_set_activated(struct view *view, bool activated);
|
||||
|
|
@ -427,6 +438,7 @@ void view_adjust_size(struct view *view, int *w, int *h);
|
|||
|
||||
void view_evacuate_region(struct view *view);
|
||||
void view_on_output_destroy(struct view *view);
|
||||
void view_connect_map(struct view *view, struct wlr_surface *surface);
|
||||
void view_destroy(struct view *view);
|
||||
|
||||
enum view_axis view_axis_parse(const char *direction);
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ struct xwayland_unmanaged {
|
|||
struct wlr_scene_node *node;
|
||||
struct wl_list link;
|
||||
|
||||
struct mappable mappable;
|
||||
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
struct wl_listener request_activate;
|
||||
struct wl_listener request_configure;
|
||||
/* struct wl_listener request_fullscreen; */
|
||||
struct wl_listener set_geometry;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener set_override_redirect;
|
||||
};
|
||||
|
|
@ -28,6 +30,8 @@ struct xwayland_view {
|
|||
struct wlr_xwayland_surface *xwayland_surface;
|
||||
|
||||
/* Events unique to XWayland views */
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
struct wl_listener request_activate;
|
||||
struct wl_listener request_configure;
|
||||
struct wl_listener set_class;
|
||||
|
|
|
|||
|
|
@ -89,9 +89,9 @@ drag_icon_create(struct seat *seat, struct wlr_drag_icon *wlr_icon)
|
|||
self->events.unmap.notify = handle_icon_unmap;
|
||||
self->events.destroy.notify = handle_icon_destroy;
|
||||
|
||||
wl_signal_add(&wlr_icon->events.map, &self->events.map);
|
||||
wl_signal_add(&wlr_icon->surface->events.map, &self->events.map);
|
||||
wl_signal_add(&wlr_icon->surface->events.commit, &self->events.commit);
|
||||
wl_signal_add(&wlr_icon->events.unmap, &self->events.unmap);
|
||||
wl_signal_add(&wlr_icon->surface->events.unmap, &self->events.unmap);
|
||||
wl_signal_add(&wlr_icon->events.destroy, &self->events.destroy);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,8 +175,8 @@ handle_surface_commit(struct wl_listener *listener, void *data)
|
|||
process_keyboard_interactivity(layer);
|
||||
}
|
||||
|
||||
if (committed || layer->mapped != layer_surface->mapped) {
|
||||
layer->mapped = layer_surface->mapped;
|
||||
if (committed || layer->mapped != layer_surface->surface->mapped) {
|
||||
layer->mapped = layer_surface->surface->mapped;
|
||||
output_update_usable_area(output);
|
||||
/*
|
||||
* Update cursor focus here to ensure we
|
||||
|
|
@ -401,10 +401,10 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
|
|||
&surface->surface_commit);
|
||||
|
||||
surface->map.notify = handle_map;
|
||||
wl_signal_add(&layer_surface->events.map, &surface->map);
|
||||
wl_signal_add(&layer_surface->surface->events.map, &surface->map);
|
||||
|
||||
surface->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&layer_surface->events.unmap, &surface->unmap);
|
||||
wl_signal_add(&layer_surface->surface->events.unmap, &surface->unmap);
|
||||
|
||||
surface->new_popup.notify = handle_new_popup;
|
||||
wl_signal_add(&layer_surface->events.new_popup, &surface->new_popup);
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ refocus_output(struct session_lock_output *output)
|
|||
|
||||
struct session_lock_output *iter;
|
||||
wl_list_for_each(iter, &output->lock->session_lock_outputs, link) {
|
||||
if (iter == output || !iter->surface) {
|
||||
if (iter == output || !iter->surface || !iter->surface->surface) {
|
||||
continue;
|
||||
}
|
||||
if (iter->surface->mapped) {
|
||||
if (iter->surface->surface->mapped) {
|
||||
focus_surface(output->lock, iter->surface->surface);
|
||||
return;
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ found_lock_output:
|
|||
wl_signal_add(&lock_surface->events.destroy, &lock_output->surface_destroy);
|
||||
|
||||
lock_output->surface_map.notify = handle_surface_map;
|
||||
wl_signal_add(&lock_surface->events.map, &lock_output->surface_map);
|
||||
wl_signal_add(&lock_surface->surface->events.map, &lock_output->surface_map);
|
||||
|
||||
lock_output_reconfigure(lock_output);
|
||||
}
|
||||
|
|
|
|||
55
src/view.c
55
src/view.c
|
|
@ -1605,6 +1605,55 @@ view_toggle_keybinds(struct view *view)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
|
||||
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap)
|
||||
{
|
||||
assert(mappable);
|
||||
assert(!mappable->connected);
|
||||
mappable->map.notify = notify_map;
|
||||
wl_signal_add(&surface->events.map, &mappable->map);
|
||||
mappable->unmap.notify = notify_unmap;
|
||||
wl_signal_add(&surface->events.unmap, &mappable->unmap);
|
||||
mappable->connected = true;
|
||||
}
|
||||
|
||||
void
|
||||
mappable_disconnect(struct mappable *mappable)
|
||||
{
|
||||
assert(mappable);
|
||||
assert(mappable->connected);
|
||||
wl_list_remove(&mappable->map.link);
|
||||
wl_list_remove(&mappable->unmap.link);
|
||||
mappable->connected = false;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_map(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, mappable.map);
|
||||
view->impl->map(view);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_unmap(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, mappable.unmap);
|
||||
view->impl->unmap(view, /* client_request */ true);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: after the release of wlroots 0.17, consider incorporating this
|
||||
* function into a more general view_set_surface() function, which could
|
||||
* connect other surface event handlers (like commit) as well.
|
||||
*/
|
||||
void
|
||||
view_connect_map(struct view *view, struct wlr_surface *surface)
|
||||
{
|
||||
assert(view);
|
||||
mappable_connect(&view->mappable, surface, handle_map, handle_unmap);
|
||||
}
|
||||
|
||||
void
|
||||
view_destroy(struct view *view)
|
||||
{
|
||||
|
|
@ -1612,8 +1661,10 @@ view_destroy(struct view *view)
|
|||
struct server *server = view->server;
|
||||
bool need_cursor_update = false;
|
||||
|
||||
wl_list_remove(&view->map.link);
|
||||
wl_list_remove(&view->unmap.link);
|
||||
if (view->mappable.connected) {
|
||||
mappable_disconnect(&view->mappable);
|
||||
}
|
||||
|
||||
wl_list_remove(&view->request_move.link);
|
||||
wl_list_remove(&view->request_resize.link);
|
||||
wl_list_remove(&view->request_minimize.link);
|
||||
|
|
|
|||
17
src/xdg.c
17
src/xdg.c
|
|
@ -163,20 +163,6 @@ set_pending_configure_serial(struct view *view, uint32_t serial)
|
|||
CONFIGURE_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_map(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, map);
|
||||
view->impl->map(view);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_unmap(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, unmap);
|
||||
view->impl->unmap(view, /* client_request */ true);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
@ -688,8 +674,7 @@ xdg_surface_new(struct wl_listener *listener, void *data)
|
|||
/* In support of xdg popups */
|
||||
xdg_surface->surface->data = tree;
|
||||
|
||||
CONNECT_SIGNAL(xdg_surface, view, map);
|
||||
CONNECT_SIGNAL(xdg_surface, view, unmap);
|
||||
view_connect_map(view, xdg_surface->surface);
|
||||
CONNECT_SIGNAL(xdg_surface, view, destroy);
|
||||
|
||||
struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static void
|
|||
handle_map(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, map);
|
||||
wl_container_of(listener, unmanaged, mappable.map);
|
||||
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
||||
assert(!unmanaged->node);
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ static void
|
|||
handle_unmap(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, unmap);
|
||||
wl_container_of(listener, unmanaged, mappable.unmap);
|
||||
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
||||
struct seat *seat = &unmanaged->server->seat;
|
||||
assert(unmanaged->node);
|
||||
|
|
@ -116,16 +116,43 @@ handle_unmap(struct wl_listener *listener, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_associate(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, associate);
|
||||
assert(unmanaged->xwayland_surface &&
|
||||
unmanaged->xwayland_surface->surface);
|
||||
|
||||
mappable_connect(&unmanaged->mappable,
|
||||
unmanaged->xwayland_surface->surface,
|
||||
handle_map, handle_unmap);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_dissociate(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, dissociate);
|
||||
|
||||
mappable_disconnect(&unmanaged->mappable);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, destroy);
|
||||
|
||||
if (unmanaged->mappable.connected) {
|
||||
mappable_disconnect(&unmanaged->mappable);
|
||||
}
|
||||
|
||||
wl_list_remove(&unmanaged->associate.link);
|
||||
wl_list_remove(&unmanaged->dissociate.link);
|
||||
wl_list_remove(&unmanaged->request_configure.link);
|
||||
wl_list_remove(&unmanaged->set_override_redirect.link);
|
||||
wl_list_remove(&unmanaged->request_activate.link);
|
||||
wl_list_remove(&unmanaged->map.link);
|
||||
wl_list_remove(&unmanaged->unmap.link);
|
||||
wl_list_remove(&unmanaged->destroy.link);
|
||||
free(unmanaged);
|
||||
}
|
||||
|
|
@ -139,9 +166,9 @@ handle_set_override_redirect(struct wl_listener *listener, void *data)
|
|||
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
||||
struct server *server = unmanaged->server;
|
||||
|
||||
bool mapped = xsurface->mapped;
|
||||
bool mapped = xsurface->surface && xsurface->surface->mapped;
|
||||
if (mapped) {
|
||||
handle_unmap(&unmanaged->unmap, NULL);
|
||||
handle_unmap(&unmanaged->mappable.unmap, NULL);
|
||||
}
|
||||
handle_destroy(&unmanaged->destroy, NULL);
|
||||
|
||||
|
|
@ -155,7 +182,7 @@ handle_request_activate(struct wl_listener *listener, void *data)
|
|||
struct xwayland_unmanaged *unmanaged =
|
||||
wl_container_of(listener, unmanaged, request_activate);
|
||||
struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (!xsurface->surface || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
struct server *server = unmanaged->server;
|
||||
|
|
@ -191,14 +218,14 @@ xwayland_unmanaged_create(struct server *server,
|
|||
*/
|
||||
assert(!xsurface->data);
|
||||
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, map);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, unmap);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, associate);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, dissociate);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, destroy);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, request_activate);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, request_configure);
|
||||
CONNECT_SIGNAL(xsurface, unmanaged, set_override_redirect);
|
||||
|
||||
if (mapped) {
|
||||
handle_map(&unmanaged->map, xsurface);
|
||||
handle_map(&unmanaged->mappable.map, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "workspaces.h"
|
||||
#include "xwayland.h"
|
||||
|
||||
static void xwayland_view_unmap(struct view *view, bool client_request);
|
||||
|
||||
static struct view_size_hints
|
||||
xwayland_view_get_size_hints(struct view *view)
|
||||
{
|
||||
|
|
@ -225,17 +227,24 @@ handle_request_resize(struct wl_listener *listener, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
handle_map(struct wl_listener *listener, void *data)
|
||||
handle_associate(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, map);
|
||||
view->impl->map(view);
|
||||
struct xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, associate);
|
||||
assert(xwayland_view->xwayland_surface &&
|
||||
xwayland_view->xwayland_surface->surface);
|
||||
|
||||
view_connect_map(&xwayland_view->base,
|
||||
xwayland_view->xwayland_surface->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_unmap(struct wl_listener *listener, void *data)
|
||||
handle_dissociate(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct view *view = wl_container_of(listener, view, unmap);
|
||||
view->impl->unmap(view, /* client_request */ true);
|
||||
struct xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, dissociate);
|
||||
|
||||
mappable_disconnect(&xwayland_view->base.mappable);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -275,6 +284,8 @@ handle_destroy(struct wl_listener *listener, void *data)
|
|||
xwayland_view->xwayland_surface = NULL;
|
||||
|
||||
/* Remove XWayland view specific listeners */
|
||||
wl_list_remove(&xwayland_view->associate.link);
|
||||
wl_list_remove(&xwayland_view->dissociate.link);
|
||||
wl_list_remove(&xwayland_view->request_activate.link);
|
||||
wl_list_remove(&xwayland_view->request_configure.link);
|
||||
wl_list_remove(&xwayland_view->set_class.link);
|
||||
|
|
@ -434,9 +445,9 @@ handle_set_override_redirect(struct wl_listener *listener, void *data)
|
|||
struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface;
|
||||
|
||||
struct server *server = view->server;
|
||||
bool mapped = xsurface->mapped;
|
||||
bool mapped = xsurface->surface && xsurface->surface->mapped;
|
||||
if (mapped) {
|
||||
handle_unmap(&view->unmap, xsurface);
|
||||
xwayland_view_unmap(view, /* client_request */ true);
|
||||
}
|
||||
handle_destroy(&view->destroy, xsurface);
|
||||
/* view is invalid after this point */
|
||||
|
|
@ -770,8 +781,6 @@ xwayland_view_create(struct server *server,
|
|||
view->scene_tree = wlr_scene_tree_create(view->workspace->tree);
|
||||
node_descriptor_create(&view->scene_tree->node, LAB_NODE_DESC_VIEW, view);
|
||||
|
||||
CONNECT_SIGNAL(xsurface, view, map);
|
||||
CONNECT_SIGNAL(xsurface, view, unmap);
|
||||
CONNECT_SIGNAL(xsurface, view, destroy);
|
||||
CONNECT_SIGNAL(xsurface, view, request_minimize);
|
||||
CONNECT_SIGNAL(xsurface, view, request_maximize);
|
||||
|
|
@ -781,6 +790,8 @@ xwayland_view_create(struct server *server,
|
|||
CONNECT_SIGNAL(xsurface, view, set_title);
|
||||
|
||||
/* Events specific to XWayland views */
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, associate);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, dissociate);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, request_activate);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, request_configure);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, set_class);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[wrap-git]
|
||||
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||
revision = 0bb574239d3b164596677bf4cec371ff0671dc4f
|
||||
revision = 26676c8c072f813dc2d7e2b2dfe9e2701ce361a7
|
||||
|
||||
[provide]
|
||||
dependency_names = wlroots
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue