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;
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;
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);
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);
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;
};
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;
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);
}
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
&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);
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;
}
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);
}
}
}
+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)
{
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);
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)
{
/* 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;
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);
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);
}
}
+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);
}
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);
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;
*/
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);
}
}
#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)
{
}
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
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);
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 */
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);
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);
[wrap-git]
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
-revision = 0bb574239d3b164596677bf4cec371ff0671dc4f
+revision = 26676c8c072f813dc2d7e2b2dfe9e2701ce361a7
[provide]
dependency_names = wlroots