struct wl_listener request_resize;
struct wl_listener request_configure;
struct wl_listener request_maximize;
- struct wl_listener new_popup; /* xdg-shell only */
+ struct wl_listener new_popup; /* xdg-shell only */
+ struct wl_listener new_subsurface; /* xdg-shell only */
};
#if HAVE_XWAYLAND
};
#endif
+struct view_child {
+ struct wlr_surface *surface;
+ struct view *parent;
+ struct wl_listener commit;
+ struct wl_listener new_subsurface;
+};
+
+struct view_subsurface {
+ struct view_child view_child;
+ struct wlr_subsurface *subsurface;
+ struct wl_listener destroy;
+};
+
struct xdg_popup {
+ struct view_child view_child;
struct wlr_xdg_popup *wlr_popup;
- struct view *view;
struct wl_listener destroy;
- struct wl_listener commit;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener new_popup;
};
+void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
+
void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
+
void xdg_surface_new(struct wl_listener *listener, void *data);
#if HAVE_XWAYLAND
struct wlr_xwayland_surface *xsurface);
#endif
+void view_child_init(struct view_child *child, struct view *view,
+ struct wlr_surface *wlr_surface);
+void view_child_finish(struct view_child *child);
+void subsurface_create(struct view *view, struct wlr_subsurface *wlr_subsurface);
+
void view_move_resize(struct view *view, struct wlr_box geo);
void view_move(struct view *view, double x, double y);
void view_minimize(struct view *view);
'output.c',
'seat.c',
'server.c',
+ 'subsurface.c',
'theme.c',
'view.c',
+ 'view-child.c',
'xdg.c',
+ 'xdg-popup.c',
)
if have_xwayland
--- /dev/null
+/*
+ * Copyright (C) 2020 the sway authors
+ * This file is only needed in support of tracking damage
+ */
+
+#include "labwc.h"
+
+static void
+subsurface_handle_destroy(struct wl_listener *listener, void *data)
+{
+ struct view_subsurface *subsurface = wl_container_of(listener,
+ subsurface, destroy);
+ struct view_child *view_child = (struct view_child *)subsurface;
+ if (!view_child) {
+ return;
+ }
+ wl_list_remove(&subsurface->destroy.link);
+ view_child_finish(&subsurface->view_child);
+ free(subsurface);
+}
+
+void
+subsurface_create(struct view *view, struct wlr_subsurface *wlr_subsurface)
+{
+ struct view_subsurface *subsurface = calloc(1, sizeof(struct view_subsurface));
+ if (!subsurface) {
+ return;
+ }
+ view_child_init(&subsurface->view_child, view, wlr_subsurface->surface);
+ subsurface->subsurface = wlr_subsurface;
+
+ subsurface->destroy.notify = subsurface_handle_destroy;
+ wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
+}
--- /dev/null
+/*
+ * Copyright (C) 2020 the sway authors
+ * This file is only needed in support of tracking damage
+ */
+
+#include "labwc.h"
+
+static void
+view_child_handle_commit(struct wl_listener *listener, void *data)
+{
+ struct view_child *child = wl_container_of(listener, child, commit);
+ damage_view_part(child->parent);
+}
+
+static void
+view_child_handle_new_subsurface(struct wl_listener *listener, void *data)
+{
+ struct view_child *child;
+ child = wl_container_of(listener, child, new_subsurface);
+ struct wlr_subsurface *wlr_subsurface = data;
+ subsurface_create(child->parent, wlr_subsurface);
+}
+
+void
+view_child_finish(struct view_child *child)
+{
+ if (!child) {
+ return;
+ }
+ damage_view_whole(child->parent);
+ wl_list_remove(&child->commit.link);
+ wl_list_remove(&child->new_subsurface.link);
+}
+
+void
+view_child_init(struct view_child *child, struct view *view,
+ struct wlr_surface *wlr_surface)
+{
+ child->parent = view;
+ child->surface = wlr_surface;
+
+ child->commit.notify = view_child_handle_commit;
+ wl_signal_add(&wlr_surface->events.commit, &child->commit);
+ child->new_subsurface.notify = view_child_handle_new_subsurface;
+ wl_signal_add(&wlr_surface->events.new_subsurface, &child->new_subsurface);
+}
#include "labwc.h"
#include <stdio.h>
-#include <assert.h>
+
void
view_move_resize(struct view *view, struct wlr_box geo)
{
--- /dev/null
+/*
+ * Copyright (C) 2020 the sway authors
+ * This file is only needed in support of tracking damage
+ */
+
+#include "labwc.h"
+
+static void
+xdg_popup_destroy(struct view_child *view_child)
+{
+ if (!view_child) {
+ return;
+ }
+ struct xdg_popup *popup = (struct xdg_popup *)view_child;
+ wl_list_remove(&popup->destroy.link);
+ wl_list_remove(&popup->map.link);
+ wl_list_remove(&popup->unmap.link);
+ wl_list_remove(&popup->new_popup.link);
+ view_child_finish(&popup->view_child);
+ free(popup);
+}
+
+static void
+handle_xdg_popup_map(struct wl_listener *listener, void *data)
+{
+ struct xdg_popup *popup = wl_container_of(listener, popup, map);
+ damage_view_whole(popup->view_child.parent);
+}
+
+static void
+handle_xdg_popup_unmap(struct wl_listener *listener, void *data)
+{
+ struct xdg_popup *popup = wl_container_of(listener, popup, unmap);
+ damage_view_whole(popup->view_child.parent);
+}
+
+static void
+handle_xdg_popup_destroy(struct wl_listener *listener, void *data)
+{
+ struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
+ struct view_child *view_child = (struct view_child *)popup;
+ xdg_popup_destroy(view_child);
+}
+
+static void
+popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
+{
+ struct xdg_popup *popup = wl_container_of(listener, popup, new_popup);
+ struct wlr_xdg_popup *wlr_popup = data;
+ xdg_popup_create(popup->view_child.parent, wlr_popup);
+}
+
+void
+xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup)
+{
+ struct xdg_popup *popup = calloc(1, sizeof(struct xdg_popup));
+ if (!popup) {
+ return;
+ }
+
+ popup->wlr_popup = wlr_popup;
+ view_child_init(&popup->view_child, view, wlr_popup->base->surface);
+
+ popup->destroy.notify = handle_xdg_popup_destroy;
+ wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
+ popup->map.notify = handle_xdg_popup_map;
+ wl_signal_add(&wlr_popup->base->events.map, &popup->map);
+ popup->unmap.notify = handle_xdg_popup_unmap;
+ wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
+ popup->new_popup.notify = popup_handle_new_xdg_popup;
+ wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
+
+ /* TODO: popup_unconstrain() */
+}
xdg_deco_request_mode(&xdg_deco->request_mode, wlr_decoration);
}
-static void
-handle_xdg_popup_commit(struct wl_listener *listener, void *data)
-{
- struct xdg_popup *popup = wl_container_of(listener, popup, map);
- /* TODO */
-}
-
-static void
-handle_xdg_popup_map(struct wl_listener *listener, void *data)
-{
- struct xdg_popup *popup = wl_container_of(listener, popup, map);
- /* damagage whole output here as popup might go outside view */
- damage_all_outputs(popup->view->server);
-}
-
-static void
-handle_xdg_popup_unmap(struct wl_listener *listener, void *data)
-{
- struct xdg_popup *popup = wl_container_of(listener, popup, unmap);
- damage_all_outputs(popup->view->server);
-}
-
-static void
-handle_xdg_popup_destroy(struct wl_listener *listener, void *data)
-{
- struct xdg_popup *popup = wl_container_of(listener, popup, destroy);
- wl_list_remove(&popup->destroy.link);
- wl_list_remove(&popup->commit.link);
- wl_list_remove(&popup->map.link);
- wl_list_remove(&popup->unmap.link);
- wl_list_remove(&popup->new_popup.link);
- free(popup);
-}
-
-static void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
-
-static void
-popup_handle_new_xdg_popup(struct wl_listener *listener, void *data)
-{
- struct xdg_popup *popup = wl_container_of(listener, popup, new_popup);
- struct wlr_xdg_popup *wlr_popup = data;
- xdg_popup_create(popup->view, wlr_popup);
-}
-
-/*
- * We need to pass view to this function for damage tracking.
- * TODO: Could we just damage surface or whole output?
- * That would allow us to only have one 'handle_new_*'
- */
-static void
-xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup)
-{
- struct xdg_popup *popup = calloc(1, sizeof(struct xdg_popup));
- if (!popup) {
- return;
- }
-
- popup->wlr_popup = wlr_popup;
- popup->view = view;
-
- popup->destroy.notify = handle_xdg_popup_destroy;
- wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
- popup->commit.notify = handle_xdg_popup_commit;
- wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
- popup->map.notify = handle_xdg_popup_map;
- wl_signal_add(&wlr_popup->base->events.map, &popup->map);
- popup->unmap.notify = handle_xdg_popup_unmap;
- wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
- popup->new_popup.notify = popup_handle_new_xdg_popup;
- wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
-}
-
/* This is merely needed to track damage */
static void
handle_new_xdg_popup(struct wl_listener *listener, void *data)
xdg_popup_create(view, wlr_popup);
}
+static void
+new_subsurface_notify(struct wl_listener *listener, void *data)
+{
+ struct view *view = wl_container_of(listener, view, new_subsurface);
+ struct wlr_subsurface *wlr_subsurface = data;
+ subsurface_create(view, wlr_subsurface);
+}
+
static bool
has_ssd(struct view *view)
{
}
view->been_mapped = true;
- wl_signal_add(&view->xdg_surface->surface->events.commit,
- &view->commit);
view->commit.notify = handle_commit;
+ wl_signal_add(&view->xdg_surface->surface->events.commit,
+ &view->commit);
+ view->new_subsurface.notify = new_subsurface_notify;
+ wl_signal_add(&view->surface->events.new_subsurface,
+ &view->new_subsurface);
desktop_focus_view(&view->server->seat, view);
damage_all_outputs(view->server);
view->mapped = false;
damage_all_outputs(view->server);
wl_list_remove(&view->commit.link);
+ wl_list_remove(&view->new_subsurface.link);
desktop_focus_topmost_mapped_view(view->server);
}