// SPDX-License-Identifier: GPL-2.0-only
+#include <assert.h>
#include "labwc.h"
#include "view.h"
#include "workspaces.h"
return;
}
- struct wlr_output *wlr_output = view_wlr_output(view);
- if (!wlr_output) {
- wlr_log(WLR_ERROR, "no wlr_output for (%s)",
- view_get_string_prop(view, "title"));
- return;
- }
- wlr_foreign_toplevel_handle_v1_output_enter(toplevel->handle, wlr_output);
-
toplevel->maximize.notify = handle_request_maximize;
wl_signal_add(&toplevel->handle->events.request_maximize,
&toplevel->maximize);
toplevel->destroy.notify = handle_destroy;
wl_signal_add(&toplevel->handle->events.destroy, &toplevel->destroy);
}
+
+/*
+ * Loop over all outputs and notify foreign_toplevel clients about changes.
+ * wlr_foreign_toplevel_handle_v1_output_xxx() keeps track of the active
+ * outputs internally and merges the events. It also listens to output
+ * destroy events so its fine to just relay the current state and let
+ * wlr_foreign_toplevel handle the rest.
+ */
+void
+foreign_toplevel_update_outputs(struct view *view)
+{
+ assert(view->toplevel.handle);
+
+ struct wlr_box view_geo = { view->x, view->y, view->w, view->h };
+ struct wlr_output_layout *layout = view->server->output_layout;
+
+ struct output *output;
+ wl_list_for_each(output, &view->server->outputs, link) {
+ if (output->wlr_output->enabled && !output->leased) {
+ if (wlr_output_layout_intersects(layout,
+ output->wlr_output, &view_geo)) {
+ wlr_foreign_toplevel_handle_v1_output_enter(
+ view->toplevel.handle, output->wlr_output);
+ continue;
+ }
+ }
+ wlr_foreign_toplevel_handle_v1_output_leave(
+ view->toplevel.handle, output->wlr_output);
+ }
+}
view_discover_output(view);
ssd_update_geometry(view->ssd);
cursor_update_focus(view->server);
+ if (view->toplevel.handle) {
+ foreign_toplevel_update_outputs(view);
+ }
}
/* N.B. Use view_move() if not resizing. */
view_center(view);
}
}
-}
-
-static void
-view_output_enter(struct view *view, struct wlr_output *wlr_output)
-{
if (view->toplevel.handle) {
- wlr_foreign_toplevel_handle_v1_output_enter(
- view->toplevel.handle, wlr_output);
- }
-}
-
-static void
-view_output_leave(struct view *view, struct wlr_output *wlr_output)
-{
- if (view->toplevel.handle) {
- wlr_foreign_toplevel_handle_v1_output_leave(
- view->toplevel.handle, wlr_output);
+ foreign_toplevel_update_outputs(view);
}
}
view_discover_output(struct view *view)
{
assert(view);
- struct output *old_output = view->output;
- struct output *new_output = view_output(view);
- if (old_output != new_output) {
- view->output = new_output;
- if (new_output) {
- view_output_enter(view, new_output->wlr_output);
- }
- if (old_output) {
- view_output_leave(view, old_output->wlr_output);
- }
- }
+ view->output = view_output(view);
}
void
view_on_output_destroy(struct view *view)
{
assert(view);
- view_output_leave(view, view->output->wlr_output);
view->output = NULL;
}