#include <wlr/util/box.h>
#include "ssd.h"
+/*
+ * In labwc, a view is a container for surfaces which can be moved around by
+ * the user. In practice this means XDG toplevel and XWayland windows.
+ */
+
enum view_type {
LAB_XDG_SHELL_VIEW,
#if HAVE_XWAYLAND
struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;
- struct wl_listener request_configure; /* xwayland only */
struct wl_listener request_activate;
struct wl_listener request_minimize;
struct wl_listener request_maximize;
struct wl_listener request_fullscreen;
struct wl_listener set_title;
- struct wl_listener set_app_id; /* class on xwayland */
- struct wl_listener set_decorations; /* xwayland only */
- struct wl_listener override_redirect; /* xwayland only */
- struct wl_listener new_popup; /* xdg-shell only */
+};
+
+struct xdg_toplevel_view {
+ struct view base;
+
+ /* Events unique to xdg-toplevel views */
+ struct wl_listener set_app_id;
+ struct wl_listener new_popup;
+};
+
+#if HAVE_XWAYLAND
+struct xwayland_view {
+ struct view base;
+
+ /* Events unique to XWayland views */
+ struct wl_listener request_configure;
+ struct wl_listener set_app_id; /* TODO: s/set_app_id/class/ */
+ struct wl_listener set_decorations;
+ struct wl_listener override_redirect;
/* Not (yet) implemented */
/* struct wl_listener set_role; */
/* struct wl_listener set_window_type; */
/* struct wl_listener set_hints; */
};
+#endif
void view_set_activated(struct view *view);
void view_close(struct view *view);
static void
handle_new_xdg_popup(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, new_popup);
+ struct xdg_toplevel_view *xdg_toplevel_view =
+ wl_container_of(listener, xdg_toplevel_view, new_popup);
+ struct view *view = &xdg_toplevel_view->base;
struct wlr_xdg_popup *wlr_popup = data;
xdg_popup_create(view, wlr_popup);
}
static void
handle_set_app_id(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, set_app_id);
+ struct xdg_toplevel_view *xdg_toplevel_view =
+ wl_container_of(listener, xdg_toplevel_view, set_app_id);
+ struct view *view = &xdg_toplevel_view->base;
assert(view);
view_update_app_id(view);
}
wlr_xdg_surface_ping(xdg_surface);
- struct view *view = znew(*view);
+ struct xdg_toplevel_view *xdg_toplevel_view = znew(*xdg_toplevel_view);
+ struct view *view = &xdg_toplevel_view->base;
+
view->server = server;
view->type = LAB_XDG_SHELL_VIEW;
view->impl = &xdg_toplevel_view_impl;
view->destroy.notify = handle_destroy;
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
- view->new_popup.notify = handle_new_xdg_popup;
- wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup);
-
struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel;
view->request_move.notify = handle_request_move;
wl_signal_add(&toplevel->events.request_move, &view->request_move);
view->set_title.notify = handle_set_title;
wl_signal_add(&toplevel->events.set_title, &view->set_title);
- view->set_app_id.notify = handle_set_app_id;
- wl_signal_add(&toplevel->events.set_app_id, &view->set_app_id);
+ /* Events specific to XDG toplevel views */
+ xdg_toplevel_view->set_app_id.notify = handle_set_app_id;
+ wl_signal_add(&toplevel->events.set_app_id, &xdg_toplevel_view->set_app_id);
+
+ xdg_toplevel_view->new_popup.notify = handle_new_xdg_popup;
+ wl_signal_add(&xdg_surface->events.new_popup, &xdg_toplevel_view->new_popup);
wl_list_insert(&server->views, &view->link);
}
#include "view.h"
#include "workspaces.h"
+static struct xwayland_view *
+xwayland_view_from_view(struct view *view)
+{
+ assert(view->type == LAB_XWAYLAND_VIEW);
+ return (struct xwayland_view *)view;
+}
+
static void
handle_commit(struct wl_listener *listener, void *data)
{
wl_list_remove(&view->surface_destroy.link);
}
+
+
static void
handle_destroy(struct wl_listener *listener, void *data)
{
wl_list_remove(&view->unmap.link);
wl_list_remove(&view->request_move.link);
wl_list_remove(&view->request_resize.link);
- wl_list_remove(&view->request_configure.link);
wl_list_remove(&view->request_activate.link);
wl_list_remove(&view->request_minimize.link);
wl_list_remove(&view->request_maximize.link);
wl_list_remove(&view->request_fullscreen.link);
wl_list_remove(&view->set_title.link);
- wl_list_remove(&view->set_app_id.link);
- wl_list_remove(&view->set_decorations.link);
- wl_list_remove(&view->override_redirect.link);
+
+ struct xwayland_view *xwayland_view = xwayland_view_from_view(view);
+ wl_list_remove(&xwayland_view->request_configure.link);
+ wl_list_remove(&xwayland_view->set_app_id.link);
+ wl_list_remove(&xwayland_view->set_decorations.link);
+ wl_list_remove(&xwayland_view->override_redirect.link);
+
wl_list_remove(&view->destroy.link);
/* And finally destroy / free the view */
static void
handle_request_configure(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, request_configure);
+ struct xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, request_configure);
+ struct view *view = &xwayland_view->base;
struct wlr_xwayland_surface_configure_event *event = data;
int width = event->width;
static void
handle_set_class(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, set_app_id);
+ struct xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, set_app_id);
+ struct view *view = &xwayland_view->base;
assert(view);
view_update_app_id(view);
}
static void
handle_set_decorations(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, set_decorations);
+ struct xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, set_decorations);
+ struct view *view = &xwayland_view->base;
view_set_decorations(view, want_deco(view));
}
static void
handle_override_redirect(struct wl_listener *listener, void *data)
{
- struct view *view = wl_container_of(listener, view, override_redirect);
+ struct xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, override_redirect);
+ struct view *view = &xwayland_view->base;
struct wlr_xwayland_surface *xsurface = data;
assert(xsurface && xsurface == view->xwayland_surface);
struct server *server = view->server;
return;
}
- struct view *view = znew(*view);
+ struct xwayland_view *xwayland_view = znew(*xwayland_view);
+ struct view *view = &xwayland_view->base;
+
view->server = server;
view->type = LAB_XWAYLAND_VIEW;
view->impl = &xwl_view_impl;
wl_signal_add(&xsurface->events.unmap, &view->unmap);
view->destroy.notify = handle_destroy;
wl_signal_add(&xsurface->events.destroy, &view->destroy);
- view->request_configure.notify = handle_request_configure;
- wl_signal_add(&xsurface->events.request_configure, &view->request_configure);
view->request_activate.notify = handle_request_activate;
wl_signal_add(&xsurface->events.request_activate, &view->request_activate);
view->request_minimize.notify = handle_request_minimize;
view->set_title.notify = handle_set_title;
wl_signal_add(&xsurface->events.set_title, &view->set_title);
- view->set_app_id.notify = handle_set_class;
- wl_signal_add(&xsurface->events.set_class, &view->set_app_id);
+ /* Events specific to XWayland views */
+ xwayland_view->request_configure.notify = handle_request_configure;
+ wl_signal_add(&xsurface->events.request_configure,
+ &xwayland_view->request_configure);
+
+ xwayland_view->set_app_id.notify = handle_set_class;
+ wl_signal_add(&xsurface->events.set_class, &xwayland_view->set_app_id);
- view->set_decorations.notify = handle_set_decorations;
+ xwayland_view->set_decorations.notify = handle_set_decorations;
wl_signal_add(&xsurface->events.set_decorations,
- &view->set_decorations);
+ &xwayland_view->set_decorations);
- view->override_redirect.notify = handle_override_redirect;
+ xwayland_view->override_redirect.notify = handle_override_redirect;
wl_signal_add(&xsurface->events.set_override_redirect,
- &view->override_redirect);
+ &xwayland_view->override_redirect);
wl_list_insert(&view->server->views, &view->link);
}